epi 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/bin/epi +1 -1
  3. data/lib/epi/cli/command.rb +7 -0
  4. data/lib/epi/cli/commands/concerns/daemon.rb +33 -0
  5. data/lib/epi/cli/commands/config.rb +11 -3
  6. data/lib/epi/cli/commands/daemon.rb +14 -0
  7. data/lib/epi/cli/commands/help.rb +0 -0
  8. data/lib/epi/cli/commands/job.rb +1 -1
  9. data/lib/epi/cli/commands/restart.rb +16 -0
  10. data/lib/epi/cli/commands/start.rb +15 -0
  11. data/lib/epi/cli/commands/status.rb +6 -2
  12. data/lib/epi/cli/commands/stop.rb +16 -0
  13. data/lib/epi/cli.rb +1 -1
  14. data/lib/epi/connection.rb +7 -0
  15. data/lib/epi/core_ext/inflector.rb +1 -1
  16. data/lib/epi/daemon/receiver.rb +37 -0
  17. data/lib/epi/{server → daemon}/responder.rb +14 -5
  18. data/lib/epi/{server → daemon}/responders/config.rb +14 -2
  19. data/lib/epi/{server → daemon}/responders/job.rb +5 -6
  20. data/lib/epi/{server → daemon}/responders/shutdown.rb +1 -1
  21. data/lib/epi/daemon/responders/start.rb +19 -0
  22. data/lib/epi/{server → daemon}/responders/status.rb +4 -2
  23. data/lib/epi/daemon/responders/stop_all.rb +20 -0
  24. data/lib/epi/daemon/sender.rb +74 -0
  25. data/lib/epi/{server.rb → daemon.rb} +26 -27
  26. data/lib/epi/data.rb +4 -5
  27. data/lib/epi/job.rb +60 -2
  28. data/lib/epi/job_description.rb +6 -8
  29. data/lib/epi/jobs.rb +30 -2
  30. data/lib/epi/launch.rb +1 -1
  31. data/lib/epi/logging.rb +33 -0
  32. data/lib/epi/process_status.rb +1 -1
  33. data/lib/epi/running_process.rb +21 -3
  34. data/lib/epi/trigger.rb +53 -0
  35. data/lib/epi/triggers/concerns/comparison.rb +43 -0
  36. data/lib/epi/triggers/memory.rb +16 -0
  37. data/lib/epi/triggers/touch.rb +37 -0
  38. data/lib/epi/triggers/uptime.rb +12 -0
  39. data/lib/epi/version.rb +1 -1
  40. data/lib/epi.rb +4 -22
  41. metadata +26 -26
  42. data/lib/epi/cli/commands/server.rb +0 -38
  43. data/lib/epi/server/receiver.rb +0 -46
  44. data/lib/epi/server/responders/command.rb +0 -15
  45. data/lib/epi/server/sender.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65b6f4c3b4d118849bb76a9bb617296e7abfc0d0
4
- data.tar.gz: 01905d5290fbadfe2ab466a0c6d593c88a3b0a7d
3
+ metadata.gz: ff6e7a2df3b27a605072bbedff81ea4ebb5b7c1b
4
+ data.tar.gz: 4609bab09c0142f2206cb733d28fb22387806fa0
5
5
  SHA512:
6
- metadata.gz: a17b31c2de560b44ff2cc927eaaaee9a987bb828ea526367d8fd57da134f651ca5a99e3c91e7f9b22db80383e3272835bf1a4bc569368741bc74ee95a98ffd6e
7
- data.tar.gz: f1c1de71a10027df1c70c137716034eec7a462f729383f81552e4f7132844956bd3a15e20b240d430cff8f6e941b6a0cb5f5da0a11a72f1cc21c1acd59a114df
6
+ metadata.gz: bb50900af4312e6959956ec5a61af06f7dee51d8f509577e56eb55027c23a7a7c43e6dd2ea4ec03425e1bc0f880d9926e094667f55b0a7eb2d7b2c3ace8427bb
7
+ data.tar.gz: 491f3d33d0b2be9d558f159c0ac8f502a037cbea1536444c4a53ea9c77739f208ebe05507c0c895fc47e2e4b3be29401618abba1ff3ea17448b283e23c5e3608
data/bin/epi CHANGED
@@ -8,7 +8,7 @@ if $0 == __FILE__
8
8
  %w[INT TERM].each do |s|
9
9
  Signal.trap(s) do
10
10
  puts " #{s} => bye for now!"
11
- EventMachine.stop
11
+ EventMachine.stop rescue nil
12
12
  end
13
13
  end
14
14
  Epi::Cli.run ARGV
@@ -19,8 +19,15 @@ module Epi
19
19
  @args = args
20
20
  end
21
21
 
22
+ def need_root!
23
+ process = Epi::Daemon.process
24
+ raise Exceptions::Fatal, 'You need root privileges to manage this daemon' if
25
+ process && process.was_alive? && process.root? && !Epi.root?
26
+ end
27
+
22
28
  end
23
29
 
30
+ Dir[File.expand_path '../commands/concerns/*.rb', __FILE__].each { |f| require f }
24
31
  Dir[File.expand_path '../commands/*.rb', __FILE__].each { |f| require f }
25
32
  end
26
33
  end
@@ -0,0 +1,33 @@
1
+ module Epi
2
+ module Cli
3
+ module Concerns
4
+ module Daemon
5
+
6
+ protected
7
+
8
+ def need_daemon!
9
+ raise Exceptions::Fatal, 'No daemon is running' unless Epi::Daemon.running?
10
+ end
11
+
12
+ def need_no_daemon!
13
+ raise Exceptions::Fatal, 'Daemon is already running' if Epi::Daemon.running?
14
+ end
15
+
16
+ def shutdown(&callback)
17
+ Epi::Daemon.send :shutdown, &callback
18
+ puts 'Shutting down ...'
19
+ end
20
+
21
+ def resume(&callback)
22
+ begin
23
+ Timeout::timeout(5) { sleep 0.05 while Epi::Daemon.socket_path.exist? }
24
+ rescue Timeout::Error
25
+ raise Exceptions::Fatal, 'Daemon failed to stop after 5 seconds'
26
+ end
27
+ Epi::Daemon.send :start, &callback
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -6,20 +6,28 @@ module Epi
6
6
  def run
7
7
  case args.shift
8
8
  when 'add' then add
9
- else raise Exceptions::Fatal, 'Unknown config command, use [ add ]'
9
+ when 'remove' then remove
10
+ else raise Exceptions::Fatal, 'Unknown config command, use [ add | remove ]'
10
11
  end
11
12
  end
12
13
 
13
14
  private
14
15
 
15
16
  def add
17
+ Epi::Daemon.send config: {add_paths: paths}
18
+ end
19
+
20
+ def remove
21
+ Epi::Daemon.send config: {remove_paths: paths}
22
+ end
23
+
24
+ def paths
16
25
  raise Exceptions::Fatal, 'No path given' unless args.first
17
- paths = args.map do |path|
26
+ @paths ||= args.map do |path|
18
27
  path = Pathname(path)
19
28
  path = Pathname('.').realpath.join(path) unless path.absolute?
20
29
  path.to_s
21
30
  end
22
- Epi::Server.send config: {add_paths: paths}
23
31
  end
24
32
 
25
33
  end
@@ -0,0 +1,14 @@
1
+ module Epi
2
+ module Cli
3
+ module Commands
4
+ class Daemon < Command
5
+
6
+ def run
7
+ Epi::Daemon.run
8
+ puts 'Daemon is running'
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
File without changes
@@ -10,7 +10,7 @@ module Epi
10
10
  raise Exceptions::Fatal, 'No instruction given' if instruction.empty?
11
11
  raise Exceptions::Fatal, 'Invalid instruction' unless
12
12
  instruction =~ /^((\d+ )?(more|less)|\d+|pause|resume|reset|max|min|restart)$/
13
- Epi::Server.send job: {id: id, instruction: instruction}
13
+ Epi::Daemon.send job: {id: id, instruction: instruction}
14
14
  end
15
15
 
16
16
  end
@@ -0,0 +1,16 @@
1
+ module Epi
2
+ module Cli
3
+ module Commands
4
+ class Restart < Command
5
+ include Concerns::Daemon
6
+
7
+ def run
8
+ need_root!
9
+ need_daemon!
10
+ Epi::Daemon.send(:stop_all) { shutdown { resume } }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Epi
2
+ module Cli
3
+ module Commands
4
+ class Start < Command
5
+ include Concerns::Daemon
6
+
7
+ def run
8
+ need_no_daemon!
9
+ Epi::Daemon.send :start
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -4,10 +4,14 @@ module Epi
4
4
  class Status < Command
5
5
 
6
6
  def run
7
- Epi::Server.send :status
7
+ if Epi::Daemon.running?
8
+ Epi::Daemon.send :status
9
+ else
10
+ Epi::Daemon.send(:start) { Epi::Daemon.send :status }
11
+ end
8
12
  end
9
13
 
10
14
  end
11
15
  end
12
16
  end
13
- end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Epi
2
+ module Cli
3
+ module Commands
4
+ class Stop < Command
5
+ include Concerns::Daemon
6
+
7
+ def run
8
+ need_root!
9
+ need_daemon!
10
+ Epi::Daemon.send(:stop_all) { shutdown }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/epi/cli.rb CHANGED
@@ -6,7 +6,7 @@ module Epi
6
6
  class << self
7
7
 
8
8
  def run(args)
9
- command = args.shift
9
+ command = args.shift || 'status' # The default command
10
10
  begin
11
11
  Command.run command, args
12
12
  rescue Exceptions::Fatal => error
@@ -0,0 +1,7 @@
1
+ require 'eventmachine'
2
+
3
+ module Epi
4
+ class Connection < EventMachine::Connection
5
+ include EventMachine::Protocols::ObjectProtocol
6
+ end
7
+ end
@@ -1,6 +1,6 @@
1
1
  class String
2
2
  def camelize
3
- gsub(/(^|_)[a-z\d]/) { |m| m.upcase }
3
+ gsub(/(^|_)[a-z\d]/) { |m| m[-1].upcase }
4
4
  end
5
5
  end
6
6
 
@@ -0,0 +1,37 @@
1
+ require_relative '../connection'
2
+
3
+ module Epi
4
+ module Daemon
5
+ class Receiver < Connection
6
+
7
+ def logger
8
+ Epi.logger
9
+ end
10
+
11
+ def receive_object(data)
12
+ logger.debug "Received message of type '#{data[:type]}'"
13
+ begin
14
+ Responder.run(self, data.delete(:type).to_s, data) { |result| send_object result: result }
15
+ rescue Exceptions::Shutdown
16
+ send_object result: nil
17
+ Daemon.shutdown
18
+ rescue => error
19
+ send_object error: {
20
+ class: error.class.name,
21
+ message: error.message,
22
+ backtrace: error.backtrace
23
+ }
24
+ end
25
+ end
26
+
27
+ def puts(text)
28
+ print "#{text}\n"
29
+ end
30
+
31
+ def print(text)
32
+ send_object print: text.to_s
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  module Epi
2
- module Server
2
+ module Daemon
3
3
  unless defined? Responder
4
4
  class Responder
5
5
  include Exceptions
@@ -9,13 +9,17 @@ module Epi
9
9
  # @param receiver [Receiver] The receiver that is running the responder
10
10
  # @param name [String] Name of the responder to invoke, e.g. 'command'
11
11
  # @param data [Hash] Data included in the message, to be extracted onto the responder before it is run
12
- def self.run(receiver, name, data)
12
+ def self.run(receiver, name, data, &callback)
13
13
  klass_name = name.camelize.to_sym
14
14
  klass = Responders.const_defined?(klass_name) && Responders.const_get(klass_name)
15
15
  raise Fatal, 'Unknown message type' unless Class === klass && klass < Responder
16
- responder = klass.new(receiver)
16
+ responder = klass.new(receiver, callback)
17
17
  data.each { |key, value| responder.__send__ :"#{key}=", value }
18
- responder.run
18
+ if responder.respond_to? :run_async
19
+ responder.run_async
20
+ else
21
+ yield responder.run
22
+ end
19
23
  end
20
24
 
21
25
  attr_reader :receiver
@@ -24,8 +28,9 @@ module Epi
24
28
  Epi.logger
25
29
  end
26
30
 
27
- def initialize(receiver)
31
+ def initialize(receiver, callback)
28
32
  @receiver = receiver
33
+ @callback = callback
29
34
  end
30
35
 
31
36
  def run
@@ -36,6 +41,10 @@ module Epi
36
41
  receiver.puts text
37
42
  end
38
43
 
44
+ def done(result = nil)
45
+ @callback.call result
46
+ end
47
+
39
48
  end
40
49
 
41
50
  Dir[File.expand_path '../responders/*.rb', __FILE__].each { |f| require f }
@@ -1,9 +1,9 @@
1
1
  module Epi
2
- module Server
2
+ module Daemon
3
3
  module Responders
4
4
  class Config < Responder
5
5
 
6
- attr_accessor :add_paths
6
+ attr_accessor :add_paths, :remove_paths
7
7
 
8
8
  def run
9
9
  result = []
@@ -19,6 +19,18 @@ module Epi
19
19
  result << "Added config path: #{path}"
20
20
  end
21
21
  end if add_paths
22
+ remove_paths.each do |path|
23
+ path = path.to_s
24
+ if configs.include?(path)
25
+ logger.info "Removing config path: #{path}"
26
+ # TODO: clean up any junk the config file may have left
27
+ configs.delete path
28
+ result << "Removed config path: #{path}"
29
+ else
30
+ logger.warn "Tried to remove unknown config path: #{path}"
31
+ result << "Config path not loaded: #{path}"
32
+ end
33
+ end if remove_paths
22
34
  Data.save
23
35
  Jobs.beat!
24
36
  result.join ' '
@@ -1,5 +1,5 @@
1
1
  module Epi
2
- module Server
2
+ module Daemon
3
3
  module Responders
4
4
  class Job < Responder
5
5
 
@@ -21,11 +21,11 @@ module Epi
21
21
  @job ||= Jobs[id]
22
22
  end
23
23
 
24
- def set(count, validate = true)
24
+ def set(count)
25
25
  allowed = job.allowed_processes
26
- raise Exceptions::Fatal, "Requested count #{count} is outside allowed range #{allowed}" unless !validate || allowed === count
26
+ raise Exceptions::Fatal, "Requested count #{count} is outside allowed range #{allowed}" unless allowed === count
27
27
  original = job.expected_count
28
- raise Exceptions::Fatal, "Already running #{count} process#{count != 1 ? 'es' : ''}" unless !validate || original != count
28
+ raise Exceptions::Fatal, "Already running #{count} process#{count != 1 ? 'es' : ''}" unless original != count
29
29
  job.expected_count = count
30
30
  job.sync!
31
31
  "#{count < original ? 'De' : 'In'}creasing '#{job.name}' processes by #{(original - count).abs} (from #{original} to #{count})"
@@ -59,8 +59,7 @@ module Epi
59
59
  def restart
60
60
  count = job.expected_count
61
61
  raise Exceptions::Fatal, 'This job has no processes to restart' if count == 0
62
- set 0, false
63
- set count
62
+ job.restart!
64
63
  "Replacing #{count} '#{job.name}' process#{count != 1 ? 'es' : ''}"
65
64
  end
66
65
 
@@ -1,5 +1,5 @@
1
1
  module Epi
2
- module Server
2
+ module Daemon
3
3
  module Responders
4
4
  class Shutdown < Responder
5
5
 
@@ -0,0 +1,19 @@
1
+ module Epi
2
+ module Daemon
3
+ module Responders
4
+
5
+ class Start < Responder
6
+
7
+ def run
8
+ count = Jobs.running_process_count
9
+ if count == 0
10
+ 'Starting ...'
11
+ else
12
+ "Starting #{count} process#{count == 1 ? '' : 'es'} ..."
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,7 @@
1
+ require 'yaml'
2
+
1
3
  module Epi
2
- module Server
4
+ module Daemon
3
5
  module Responders
4
6
  # noinspection RubyStringKeysInHashInspection
5
7
  class Status < Responder
@@ -14,7 +16,7 @@ module Epi
14
16
  def stats
15
17
  {
16
18
  'Running as' => `whoami`.chomp,
17
- 'Since' => Server.start_time.strftime('%c'),
19
+ 'Since' => Daemon.start_time.strftime('%c'),
18
20
  'Jobs' => jobs
19
21
  }
20
22
  end
@@ -0,0 +1,20 @@
1
+ module Epi
2
+ module Daemon
3
+ module Responders
4
+
5
+ class StopAll < Responder
6
+
7
+ def run_async
8
+ count = Jobs.running_process_count
9
+ if count > 0
10
+ puts "Stopping #{count} process#{count == 1 ? '' : 'es'} ..."
11
+ Jobs.shutdown! { done }
12
+ else
13
+ done
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,74 @@
1
+ require_relative '../connection'
2
+
3
+ module Epi
4
+ module Daemon
5
+ class Sender < Connection
6
+ include Exceptions
7
+
8
+ # Send a message to the Epi server
9
+ #
10
+ # @example Get Epi's status
11
+ # Sender.send :status
12
+ #
13
+ # @example Add a config file
14
+ # Sender.send config: {add_paths: ['config.epi']}
15
+ #
16
+ # @param what [Hash|Symbol] Either a symbol being the message type, or a hash
17
+ # with a single key (a symbol) being the message type, and value (a hash) being the message.
18
+ def self.send(what, &callback)
19
+
20
+ raise ArgumentError, 'Expected a hash with one key (a symbol) and value (a hash)' unless
21
+ Symbol === what ||
22
+ (Hash === what && what.count == 1 && Symbol === what.keys.first && Hash === what.values.first)
23
+
24
+ data = case what
25
+ when Symbol then {type: what}
26
+ when Hash then what.values.first.merge(type: what.keys.first)
27
+ else nil
28
+ end
29
+
30
+ EventMachine.connect Daemon.socket_path.to_s, Sender, data, callback
31
+
32
+ end
33
+
34
+ def initialize(data, callback)
35
+ @callback = callback
36
+ send_object data
37
+ end
38
+
39
+ def receive_object(data)
40
+ if data[:print]
41
+ STDOUT << data[:print]
42
+ return
43
+ end
44
+
45
+ if data.key? :result
46
+ result = data[:result]
47
+
48
+ if @callback
49
+ @callback.call result
50
+ else
51
+ puts result unless result.nil?
52
+ EM.stop
53
+ end
54
+
55
+ elsif data[:error]
56
+
57
+ error = data[:error]
58
+ if error[:class] == Fatal.name
59
+ STDERR << error[:message]
60
+ STDERR << "\n"
61
+ else
62
+ STDERR << "#{error[:class]}: #{error[:message]}\n"
63
+ error[:backtrace].each { |x| STDERR << "\t#{x}\n" }
64
+ end
65
+
66
+ EM.stop
67
+ end
68
+
69
+ close_connection
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -1,11 +1,11 @@
1
1
  require 'eventmachine'
2
2
 
3
- require_relative 'server/sender'
4
- require_relative 'server/receiver'
5
- require_relative 'server/responder'
3
+ require_relative 'daemon/sender'
4
+ require_relative 'daemon/receiver'
5
+ require_relative 'daemon/responder'
6
6
 
7
7
  module Epi
8
- module Server
8
+ module Daemon
9
9
 
10
10
  class << self
11
11
 
@@ -19,7 +19,7 @@ module Epi
19
19
  should_run_as_root = Data.root?
20
20
 
21
21
  if running? && should_run_as_root && !process.root?
22
- logger.info "Server needs to run as root, but is running as #{process.user}"
22
+ logger.info "Daemon needs to run as root, but is running as #{process.user}"
23
23
  shutdown
24
24
  end
25
25
 
@@ -29,15 +29,15 @@ module Epi
29
29
  'or specify EPI_HOME as a directory other than /etc/epi'
30
30
  end
31
31
 
32
- logger.info 'Starting server'
33
- Epi.launch [$0, 'server', 'run'],
34
- stdout: Data.home + 'server.log',
35
- stderr: Data.home + 'server_errors.log'
32
+ logger.info 'Starting daemon'
33
+ Epi.launch [$0, 'daemon'],
34
+ stdout: Data.home + 'daemon.log',
35
+ stderr: Data.home + 'daemon_errors.log'
36
36
 
37
37
  begin
38
38
  Timeout::timeout(5) { sleep 0.05 until socket_path.exist? }
39
39
  rescue Timeout::Error
40
- raise Exceptions::Fatal, 'Server not started after 5 seconds'
40
+ raise Exceptions::Fatal, 'Daemon not started after 5 seconds'
41
41
  end unless socket_path.exist?
42
42
  end
43
43
  end
@@ -47,43 +47,42 @@ module Epi
47
47
  end
48
48
 
49
49
  def run
50
- raise Exceptions::Fatal, 'Server already running' if running?
50
+ raise Exceptions::Fatal, 'Daemon already running' if running?
51
51
 
52
- # Save the server PID
53
- Data.server_pid = Process.pid
52
+ # Save the daemon PID
53
+ Data.daemon_pid = Process.pid
54
54
 
55
55
  # Run an initial beat
56
56
  Jobs.beat!
57
57
 
58
- # Start a server
58
+ # Start a daemon
59
59
  EventMachine.start_unix_domain_server socket_path.to_s, Receiver
60
60
  logger.info "Listening on socket #{socket_path}"
61
61
 
62
- # Make sure other users can connect to the server
62
+ # Make sure other users can connect to the daemon
63
63
  socket_path.chmod 0777 #TODO: make configurable
64
64
 
65
- # Ensure the socket is destroyed when the server exits
65
+ # Ensure the socket is destroyed when the daemon exits
66
66
  EventMachine.add_shutdown_hook { socket_path.delete }
67
67
 
68
68
  @start_time = Time.now
69
69
  end
70
70
 
71
- def send(*args)
71
+ def send(*args, &callback)
72
72
  ensure_running
73
- Sender.send *args
73
+ Sender.send *args, &callback
74
74
  end
75
75
 
76
76
  def shutdown(process = nil)
77
- process ||= self.process
78
- raise Exceptions::Fatal, 'Attempted to shut down server when no server is running' unless running?
79
- if process.pid == Process.pid
77
+ raise Exceptions::Fatal, 'Attempted to shut down daemon when no daemon is running' unless running?
78
+ if (process || self.process).pid == Process.pid
80
79
  EventMachine.next_tick do
81
80
  EventMachine.stop_event_loop
82
- Data.server_pid = nil
83
- logger.info 'Server has shut down'
81
+ Data.daemon_pid = nil
82
+ logger.info 'Daemon has shut down'
84
83
  end
85
84
  else
86
- logger.info 'Server will shut down'
85
+ logger.info 'Daemon will shut down'
87
86
  send :shutdown
88
87
  end
89
88
  end
@@ -93,9 +92,9 @@ module Epi
93
92
  end
94
93
 
95
94
  def process
96
- server_pid = Data.server_pid
97
- @process = nil if @process && @process.pid != server_pid
98
- @process ||= server_pid && RunningProcess.new(server_pid)
95
+ daemon_pid = Data.daemon_pid
96
+ @process = nil if @process && @process.pid != daemon_pid
97
+ @process ||= daemon_pid && RunningProcess.new(daemon_pid)
99
98
  end
100
99
 
101
100
  end
data/lib/epi/data.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'pathname'
2
- require 'bson'
3
2
  require 'forwardable'
4
3
 
5
4
  module Epi
@@ -13,7 +12,7 @@ module Epi
13
12
 
14
13
  delegate [:[], :[]=, :read, :write, :root?, :save, :reload, :home] => :default_instance
15
14
 
16
- %w[server_pid].each do |property|
15
+ %w[daemon_pid].each do |property|
17
16
  define_method(property) { read property }
18
17
  define_method(property + '=') { |value| write property, value }
19
18
  end
@@ -104,7 +103,7 @@ module Epi
104
103
  end
105
104
 
106
105
  def data_file
107
- @data_file ||= home + 'data.bson'
106
+ @data_file ||= home + 'data'
108
107
  end
109
108
 
110
109
  # Force reload of data from disk
@@ -114,12 +113,12 @@ module Epi
114
113
 
115
114
  # Save data to disk
116
115
  def save
117
- data_file.binwrite hash.to_bson
116
+ data_file.binwrite Marshal.dump hash
118
117
  data_file.chmod 0644
119
118
  end
120
119
 
121
120
  def hash
122
- @hash ||= data_file.exist? ? Hash.from_bson(StringIO.new data_file.binread) : {}
121
+ @hash ||= data_file.exist? ? Marshal.load(data_file.binread) : {}
123
122
  end
124
123
 
125
124
  # Returns true if using root data at /etc/epi, or false if using user data