eye 0.8.celluloid15 → 0.8.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -5
  3. data/CHANGES.md +3 -7
  4. data/README.md +2 -5
  5. data/Rakefile +6 -6
  6. data/bin/leye +4 -9
  7. data/bin/loader_eye +15 -14
  8. data/examples/delayed_job.eye +3 -3
  9. data/examples/dependency.eye +11 -10
  10. data/examples/notify.eye +4 -3
  11. data/examples/plugin/main.eye +5 -5
  12. data/examples/plugin/plugin.rb +2 -10
  13. data/examples/process_thin.rb +8 -8
  14. data/examples/processes/em.rb +12 -18
  15. data/examples/processes/forking.rb +5 -5
  16. data/examples/processes/sample.rb +44 -46
  17. data/examples/puma.eye +8 -9
  18. data/examples/rbenv.eye +5 -5
  19. data/examples/sidekiq.eye +3 -3
  20. data/examples/stress_test.eye +4 -4
  21. data/examples/syslog.eye +1 -1
  22. data/examples/test.eye +2 -1
  23. data/examples/thin-farm.eye +8 -7
  24. data/examples/triggers.eye +15 -13
  25. data/examples/unicorn.eye +13 -12
  26. data/eye.gemspec +14 -16
  27. data/lib/eye.rb +3 -2
  28. data/lib/eye/application.rb +6 -5
  29. data/lib/eye/checker.rb +25 -44
  30. data/lib/eye/checker/children_count.rb +1 -1
  31. data/lib/eye/checker/file_ctime.rb +1 -1
  32. data/lib/eye/checker/http.rb +15 -13
  33. data/lib/eye/checker/nop.rb +0 -1
  34. data/lib/eye/checker/socket.rb +63 -60
  35. data/lib/eye/checker/ssl_socket.rb +5 -5
  36. data/lib/eye/child_process.rb +4 -6
  37. data/lib/eye/cli.rb +46 -74
  38. data/lib/eye/cli/commands.rb +5 -4
  39. data/lib/eye/cli/render.rb +41 -61
  40. data/lib/eye/cli/server.rb +16 -19
  41. data/lib/eye/client.rb +0 -1
  42. data/lib/eye/config.rb +33 -36
  43. data/lib/eye/controller.rb +3 -2
  44. data/lib/eye/controller/commands.rb +1 -1
  45. data/lib/eye/controller/helpers.rb +2 -2
  46. data/lib/eye/controller/load.rb +17 -19
  47. data/lib/eye/controller/options.rb +5 -1
  48. data/lib/eye/controller/send_command.rb +23 -21
  49. data/lib/eye/controller/status.rb +15 -17
  50. data/lib/eye/dsl.rb +1 -6
  51. data/lib/eye/dsl/application_opts.rb +3 -4
  52. data/lib/eye/dsl/chain.rb +2 -2
  53. data/lib/eye/dsl/child_process_opts.rb +3 -3
  54. data/lib/eye/dsl/config_opts.rb +7 -7
  55. data/lib/eye/dsl/group_opts.rb +3 -3
  56. data/lib/eye/dsl/helpers.rb +1 -1
  57. data/lib/eye/dsl/main.rb +3 -4
  58. data/lib/eye/dsl/opts.rb +28 -31
  59. data/lib/eye/dsl/process_opts.rb +7 -13
  60. data/lib/eye/dsl/pure_opts.rb +9 -13
  61. data/lib/eye/dsl/validation.rb +35 -48
  62. data/lib/eye/group.rb +8 -23
  63. data/lib/eye/group/chain.rb +6 -6
  64. data/lib/eye/loader.rb +3 -3
  65. data/lib/eye/local.rb +4 -9
  66. data/lib/eye/logger.rb +4 -11
  67. data/lib/eye/notify.rb +6 -10
  68. data/lib/eye/notify/jabber.rb +1 -1
  69. data/lib/eye/notify/mail.rb +2 -2
  70. data/lib/eye/notify/slack.rb +3 -4
  71. data/lib/eye/process.rb +0 -2
  72. data/lib/eye/process/children.rb +4 -4
  73. data/lib/eye/process/commands.rb +39 -38
  74. data/lib/eye/process/config.rb +16 -22
  75. data/lib/eye/process/controller.rb +19 -5
  76. data/lib/eye/process/data.rb +9 -11
  77. data/lib/eye/process/monitor.rb +76 -86
  78. data/lib/eye/process/notify.rb +10 -10
  79. data/lib/eye/process/scheduler.rb +31 -36
  80. data/lib/eye/process/states.rb +5 -7
  81. data/lib/eye/process/states_history.rb +3 -9
  82. data/lib/eye/process/system.rb +20 -35
  83. data/lib/eye/process/trigger.rb +5 -1
  84. data/lib/eye/process/watchers.rb +9 -12
  85. data/lib/eye/reason.rb +1 -4
  86. data/lib/eye/server.rb +1 -2
  87. data/lib/eye/system.rb +15 -22
  88. data/lib/eye/system_resources.rb +9 -18
  89. data/lib/eye/trigger.rb +16 -18
  90. data/lib/eye/trigger/check_dependency.rb +4 -7
  91. data/lib/eye/trigger/flapping.rb +7 -24
  92. data/lib/eye/trigger/starting_guard.rb +6 -7
  93. data/lib/eye/trigger/stop_children.rb +2 -2
  94. data/lib/eye/trigger/transition.rb +1 -1
  95. data/lib/eye/trigger/wait_dependency.rb +2 -3
  96. data/lib/eye/utils.rb +3 -4
  97. data/lib/eye/utils/alive_array.rb +4 -9
  98. data/lib/eye/utils/celluloid_chain.rb +10 -12
  99. data/lib/eye/utils/leak_19.rb +10 -0
  100. data/lib/eye/utils/mini_active_support.rb +16 -16
  101. data/lib/eye/utils/pmap.rb +0 -2
  102. data/lib/eye/utils/tail.rb +2 -2
  103. metadata +8 -39
  104. data/.rubocop.yml +0 -141
  105. data/examples/custom_check.eye +0 -24
  106. data/examples/custom_trigger.eye +0 -30
  107. data/examples/leye_example/Eyefile +0 -10
@@ -5,21 +5,21 @@ module Eye::Process::Notify
5
5
  # 2) checker bounded to restart process [:warn]
6
6
  # 3) flapping + switch to unmonitored [:error]
7
7
 
8
- LEVELS = { debug: 0, info: 1, warn: 2, error: 3, fatal: 4 }
8
+ LEVELS = {:debug => 0, :info => 1, :warn => 2, :error => 3, :fatal => 4}
9
9
 
10
10
  def notify(level, msg)
11
11
  # logging it
12
12
  error "NOTIFY: #{msg}" if ilevel(level) > ilevel(:info)
13
13
 
14
- return if self[:notify].blank?
15
-
16
14
  # send notifies
17
- message = { message: msg, name: name,
18
- full_name: full_name, pid: pid, host: Eye::Local.host, level: level,
19
- at: Time.now }
20
-
21
- self[:notify].each do |contact, not_level|
22
- Eye::Notify.notify(contact, message) if ilevel(level) >= ilevel(not_level)
15
+ if self[:notify].present?
16
+ message = {:message => msg, :name => name,
17
+ :full_name => full_name, :pid => pid, :host => Eye::Local.host, :level => level,
18
+ :at => Time.now }
19
+
20
+ self[:notify].each do |contact, not_level|
21
+ Eye::Notify.notify(contact, message) if ilevel(level) >= ilevel(not_level)
22
+ end
23
23
  end
24
24
  end
25
25
 
@@ -29,4 +29,4 @@ private
29
29
  LEVELS[level].to_i
30
30
  end
31
31
 
32
- end
32
+ end
@@ -2,30 +2,32 @@ module Eye::Process::Scheduler
2
2
 
3
3
  # ex: schedule :update_config, config, "reason: update_config"
4
4
  def schedule(command, *args, &block)
5
- return unless scheduler.alive?
6
-
7
- if scheduler_freeze?
8
- warn ":#{command} ignoring to schedule, because scheduler is freeze"
9
- return
10
- end
11
-
12
- unless self.respond_to?(command, true)
13
- warn ":#{command} scheduling is unsupported"
14
- return
15
- end
16
-
17
- reason = args.pop if args.present? && args[-1].is_a?(Eye::Reason)
18
-
19
- info "schedule :#{command} #{reason ? "(reason: #{reason})" : nil}"
20
-
21
- if reason.class == Eye::Reason
22
- # for auto reasons
23
- # skip already running commands and all in chain
24
- scheduler.add_wo_dups_current(:scheduled_action, command, args: args, reason: reason, block: block)
25
- else
26
- # for manual, or without reason
27
- # skip only for last in chain
28
- scheduler.add_wo_dups(:scheduled_action, command, args: args, reason: reason, block: block)
5
+ if scheduler.alive?
6
+ if scheduler_freeze?
7
+ warn ":#{command} ignoring to schedule, because scheduler is freeze"
8
+ return
9
+ end
10
+
11
+ unless self.respond_to?(command, true)
12
+ warn ":#{command} scheduling is unsupported"
13
+ return
14
+ end
15
+
16
+ reason = if args.present? && args[-1].kind_of?(Eye::Reason)
17
+ args.pop
18
+ end
19
+
20
+ info "schedule :#{command} #{reason ? "(reason: #{reason})" : nil}"
21
+
22
+ if reason.class == Eye::Reason
23
+ # for auto reasons
24
+ # skip already running commands and all in chain
25
+ scheduler.add_wo_dups_current(:scheduled_action, command, {:args => args, :reason => reason}, &block)
26
+ else
27
+ # for manual, or without reason
28
+ # skip only for last in chain
29
+ scheduler.add_wo_dups(:scheduled_action, command, {:args => args, :reason => reason}, &block)
30
+ end
29
31
  end
30
32
  end
31
33
 
@@ -37,16 +39,16 @@ module Eye::Process::Scheduler
37
39
  end
38
40
  end
39
41
 
40
- def scheduled_action(command, h = {})
41
- reason = h[:reason]
42
- info "=> #{command} #{h[:args].present? ? "#{h[:args] * ','}" : nil} #{reason ? "(reason: #{reason})" : nil}"
42
+ def scheduled_action(command, h = {}, &block)
43
+ reason = h.delete(:reason)
44
+ info "=> #{command} #{h[:args].present? ? "#{h[:args]*',' }" : nil} #{reason ? "(reason: #{reason})" : nil}"
43
45
 
44
46
  @current_scheduled_command = command
45
47
  @last_scheduled_command = command
46
48
  @last_scheduled_reason = reason
47
49
  @last_scheduled_at = Time.now
48
50
 
49
- send(command, *h[:args], &h[:block])
51
+ send(command, *h[:args], &block)
50
52
  @current_scheduled_command = nil
51
53
  info "<= #{command}"
52
54
 
@@ -57,14 +59,8 @@ module Eye::Process::Scheduler
57
59
  end
58
60
  end
59
61
 
60
- def execute_proc(*_args, &block)
61
- self.instance_exec(&block)
62
- rescue Object => ex
63
- log_ex(ex)
64
- end
65
-
66
62
  def scheduler_actions_list
67
- scheduler.list.map { |c| c[:args].first rescue nil }.compact
63
+ scheduler.list.map{|c| c[:args].first rescue nil }.compact
68
64
  end
69
65
 
70
66
  def scheduler_clear_pending_list
@@ -73,7 +69,6 @@ module Eye::Process::Scheduler
73
69
 
74
70
  def self.included(base)
75
71
  base.finalizer :remove_scheduler
76
- base.execute_block_on_receiver :schedule
77
72
  end
78
73
 
79
74
  attr_accessor :current_scheduled_command
@@ -2,7 +2,6 @@ require 'state_machine'
2
2
  require 'state_machine/version'
3
3
 
4
4
  class Eye::Process
5
-
6
5
  class StateError < Exception; end
7
6
 
8
7
  # do transition
@@ -28,7 +27,7 @@ class Eye::Process
28
27
  end
29
28
 
30
29
  event :crashed do
31
- transition [:starting, :restarting, :stopping, :up] => :down
30
+ transition [:starting, :restarting, :up] => :down
32
31
  end
33
32
 
34
33
  event :stopping do
@@ -60,17 +59,16 @@ class Eye::Process
60
59
 
61
60
  after_transition any => :unmonitored, :do => :on_unmonitored
62
61
 
63
- after_transition any - :up => :up, :do => :add_watchers
64
- after_transition :up => any - :up, :do => :remove_watchers
62
+ after_transition any-:up => :up, :do => :add_watchers
63
+ after_transition :up => any-:up, :do => :remove_watchers
65
64
 
66
- after_transition any - :up => :up, :do => :add_children
65
+ after_transition any-:up => :up, :do => :add_children
67
66
  after_transition any => [:unmonitored, :down], :do => :remove_children
68
67
 
69
68
  after_transition :on => :crashed, :do => :on_crashed
70
69
  end
71
70
 
72
71
  def on_crashed
73
- self.pid = nil
74
72
  schedule :check_crash, Eye::Reason.new(:crashed)
75
73
  end
76
74
 
@@ -81,7 +79,7 @@ class Eye::Process
81
79
  def log_transition(transition)
82
80
  if transition.to_name != transition.from_name || @state_reason.is_a?(Eye::Reason::User)
83
81
  @states_history.push transition.to_name, @state_reason
84
- info "switch :#{transition.event} [:#{transition.from_name} => :#{transition.to_name}] #{"(reason: #{@state_reason})" if @state_reason}"
82
+ info "switch :#{transition.event} [:#{transition.from_name} => :#{transition.to_name}] #{@state_reason ? "(reason: #{@state_reason})" : nil}"
85
83
  end
86
84
  end
87
85
 
@@ -1,22 +1,17 @@
1
1
  class Eye::Process::StatesHistory < Eye::Utils::Tail
2
-
3
2
  def push(state, reason = nil, tm = Time.now)
4
3
  super(state: state, at: tm.to_i, reason: reason)
5
4
  end
6
5
 
7
6
  def states
8
- self.map { |c| c[:state] }
7
+ self.map{|c| c[:state] }
9
8
  end
10
9
 
11
- def states_for_period(period, from_time = nil, &block)
10
+ def states_for_period(period, from_time = nil)
12
11
  tm = Time.now - period
13
12
  tm = [tm, from_time].max if from_time
14
13
  tm = tm.to_f
15
- if block
16
- self.each { |s| block.call(s) if s[:at] >= tm }
17
- else
18
- self.select { |s| s[:at] >= tm }.map { |c| c[:state] }
19
- end
14
+ self.select{|s| s[:at] >= tm }.map{|c| c[:state] }
20
15
  end
21
16
 
22
17
  def last_state
@@ -30,5 +25,4 @@ class Eye::Process::StatesHistory < Eye::Utils::Tail
30
25
  def last_state_changed_at
31
26
  Time.at(last[:at])
32
27
  end
33
-
34
28
  end
@@ -3,7 +3,16 @@ require 'timeout'
3
3
  module Eye::Process::System
4
4
 
5
5
  def load_pid_from_file
6
- File.read(self[:pid_file_ex]).to_i rescue nil
6
+ res = if File.exist?(self[:pid_file_ex])
7
+ _pid = File.read(self[:pid_file_ex]).to_i
8
+ _pid > 0 ? _pid : nil
9
+ end
10
+
11
+ res
12
+ end
13
+
14
+ def set_pid_from_file
15
+ self.pid = load_pid_from_file
7
16
  end
8
17
 
9
18
  def save_pid_to_file
@@ -17,8 +26,7 @@ module Eye::Process::System
17
26
  end
18
27
  end
19
28
 
20
- def clear_pid_file(check_content = false)
21
- return if check_content && self.pid && load_pid_from_file != self.pid
29
+ def clear_pid_file
22
30
  info "delete pid_file: #{self[:pid_file_ex]}"
23
31
  File.unlink(self[:pid_file_ex])
24
32
  true
@@ -30,38 +38,14 @@ module Eye::Process::System
30
38
  File.ctime(self[:pid_file_ex]) rescue Time.now
31
39
  end
32
40
 
33
- def get_identity
34
- File.mtime(self[:pid_file_ex])
35
- rescue Errno::ENOENT
36
- nil
37
- end
38
-
39
- def compare_identity(pid = self.pid)
40
- return :ok unless self[:check_identity]
41
- return :no_pid unless pid
42
- id = get_identity
43
- return :no_pid_file unless id
44
- st = Eye::SystemResources.start_time(pid)
45
- return :no_start_time unless st
46
- st1 = st.to_i
47
- id1 = id.to_i
48
- if (id1 - st1).abs > self[:check_identity_grace]
49
- args = Eye::SystemResources.args(pid)
50
- msg = "pid_file: '#{Eye::Utils.human_time2(id)}', process: '#{Eye::Utils.human_time2(st)}' (#{args})"
51
- res = (id1 < st1) ? :fail : :touched
52
- warn "compare_identity: #{res}, #{msg}"
53
- res
54
- else
55
- :ok
56
- end
57
- end
58
-
59
41
  def process_really_running?
60
42
  process_pid_running?(self.pid)
61
43
  end
62
44
 
63
45
  def process_pid_running?(pid)
64
- Eye::System.pid_alive?(pid)
46
+ res = Eye::System.check_pid_alive(pid)
47
+ debug { "process_really_running?: <#{pid}> #{res.inspect}" }
48
+ !!res[:result]
65
49
  end
66
50
 
67
51
  def send_signal(code)
@@ -74,7 +58,7 @@ module Eye::Process::System
74
58
  res[:result] == :ok
75
59
  end
76
60
 
77
- def wait_for_condition(timeout, step = 0.1, &_block)
61
+ def wait_for_condition(timeout, step = 0.1, &block)
78
62
  res = nil
79
63
  sumtime = 0
80
64
 
@@ -89,7 +73,7 @@ module Eye::Process::System
89
73
  end
90
74
 
91
75
  def execute(cmd, cfg = {})
92
- defer { Eye::System.execute cmd, cfg }.tap do |res|
76
+ defer { Eye::System::execute cmd, cfg }.tap do |res|
93
77
  notify(:debug, "Bad exit status of command #{cmd.inspect}(#{res[:exitstatus].inspect})") if res[:exitstatus] != 0
94
78
  end
95
79
  end
@@ -98,7 +82,7 @@ module Eye::Process::System
98
82
  Eye::System.daemonize(cmd, cfg)
99
83
  end
100
84
 
101
- def execute_sync(cmd, opts = { timeout: 1.second })
85
+ def execute_sync(cmd, opts = {:timeout => 1.second})
102
86
  execute(cmd, self.config.merge(opts)).tap do |res|
103
87
  info "execute_sync `#{cmd}` with res: #{res}"
104
88
  end
@@ -113,12 +97,13 @@ module Eye::Process::System
113
97
  def failsafe_load_pid
114
98
  pid = load_pid_from_file
115
99
 
116
- unless pid # this is can be symlink changed case
100
+ if !pid
101
+ # this is can be symlink changed case
117
102
  sleep 0.1
118
103
  pid = load_pid_from_file
119
104
  end
120
105
 
121
- pid if pid && pid > 0
106
+ pid
122
107
  end
123
108
 
124
109
  def failsafe_save_pid
@@ -1,7 +1,11 @@
1
1
  module Eye::Process::Trigger
2
2
 
3
3
  def add_triggers
4
- (self[:triggers] || {}).each { |_type, cfg| add_trigger(cfg) }
4
+ if self[:triggers]
5
+ self[:triggers].each do |type, cfg|
6
+ add_trigger(cfg)
7
+ end
8
+ end
5
9
  end
6
10
 
7
11
  def remove_triggers
@@ -11,12 +11,6 @@ module Eye::Process::Watchers
11
11
  check_alive
12
12
  end
13
13
 
14
- if self[:check_identity]
15
- add_watcher(:check_identity, self[:check_identity_period]) do
16
- check_identity
17
- end
18
- end
19
-
20
14
  # monitor children pids
21
15
  if self[:monitor_children]
22
16
  add_watcher(:check_children, self[:children_update_period]) do
@@ -32,7 +26,7 @@ module Eye::Process::Watchers
32
26
  end
33
27
 
34
28
  def remove_watchers
35
- @watchers.each { |_, h| h[:timer].cancel }
29
+ @watchers.each{|_, h| h[:timer].cancel }
36
30
  @watchers = {}
37
31
  end
38
32
 
@@ -48,22 +42,25 @@ private
48
42
  block.call(subject)
49
43
  end
50
44
 
51
- @watchers[type] ||= { timer: timer, subject: subject }
45
+ @watchers[type] ||= {:timer => timer, :subject => subject}
52
46
  end
53
47
 
54
48
  def start_checkers
55
- self[:checks].each { |name, cfg| start_checker(name, cfg) }
49
+ self[:checks].each{|name, cfg| start_checker(name, cfg) }
56
50
  end
57
51
 
58
52
  def start_checker(name, cfg)
59
- # cfg: {:type => :memory, :every => 5.seconds, :below => 100.megabytes, :times => [3, 5]}
60
53
  subject = Eye::Checker.create(pid, cfg, current_actor)
54
+
55
+ # ex: {:type => :memory, :every => 5.seconds, :below => 100.megabytes, :times => [3,5]}
61
56
  add_watcher("check_#{name}".to_sym, subject.every, subject, &method(:watcher_tick).to_proc) if subject
62
57
  end
63
58
 
64
59
  def watcher_tick(subject)
65
- # double up? test needed because state can changed while subject.check
66
- subject.fire if up? && !subject.check && up?
60
+ unless subject.check
61
+ return unless up?
62
+ subject.fire
63
+ end
67
64
  end
68
65
 
69
66
  end
@@ -13,14 +13,11 @@ class Eye::Reason
13
13
  end
14
14
 
15
15
  class User < Eye::Reason
16
-
17
16
  def to_s
18
17
  "#{super} by user"
19
18
  end
20
-
21
19
  end
22
20
 
23
21
  class Flapping < Eye::Reason; end
24
22
  class StartingGuard < Eye::Reason; end
25
-
26
- end
23
+ end
@@ -1,8 +1,7 @@
1
- require 'celluloid/autostart'
2
1
  require 'celluloid/io'
2
+ require 'celluloid/current'
3
3
 
4
4
  class Eye::Server
5
-
6
5
  include Celluloid::IO
7
6
 
8
7
  attr_reader :socket_path, :server
@@ -3,9 +3,7 @@ require 'etc'
3
3
  require 'timeout'
4
4
 
5
5
  module Eye::System
6
-
7
6
  class << self
8
-
9
7
  # Check that pid really exits
10
8
  # very fast
11
9
  # return result hash
@@ -16,21 +14,17 @@ module Eye::System
16
14
  false
17
15
  end
18
16
 
19
- { result: res }
17
+ {:result => res}
20
18
  rescue => ex
21
- { error: ex }
19
+ {:error => ex}
22
20
  end
23
21
 
24
22
  # Check that pid really exits
25
23
  # very fast
26
24
  # return true/false
27
25
  def pid_alive?(pid)
28
- if pid
29
- ::Process.kill(0, pid)
30
- true
31
- end
32
- rescue
33
- false
26
+ res = check_pid_alive(pid)
27
+ !!res[:result]
34
28
  end
35
29
 
36
30
  # Send signal to process (uses for kill)
@@ -45,13 +39,13 @@ module Eye::System
45
39
 
46
40
  if pid
47
41
  ::Process.kill(code, pid)
48
- { result: :ok }
42
+ {:result => :ok}
49
43
  else
50
- { error: Exception.new('no_pid') }
44
+ {:error => Exception.new('no_pid')}
51
45
  end
52
46
 
53
47
  rescue => ex
54
- { error: ex }
48
+ {:error => ex}
55
49
  end
56
50
 
57
51
  # Daemonize cmd, and detach
@@ -61,12 +55,12 @@ module Eye::System
61
55
  # :environment
62
56
  # :stdin, :stdout, :stderr
63
57
  def daemonize(cmd, cfg = {})
64
- pid = ::Process.spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
58
+ pid = ::Process::spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
65
59
 
66
- { pid: pid, exitstatus: 0 }
60
+ {:pid => pid, :exitstatus => 0}
67
61
 
68
62
  rescue Errno::ENOENT, Errno::EACCES => ex
69
- { error: ex }
63
+ {:error => ex}
70
64
 
71
65
  ensure
72
66
  Process.detach(pid) if pid
@@ -78,7 +72,7 @@ module Eye::System
78
72
  # :environment
79
73
  # :stdin, :stdout, :stderr
80
74
  def execute(cmd, cfg = {})
81
- pid = ::Process.spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
75
+ pid = ::Process::spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
82
76
 
83
77
  timeout = cfg[:timeout] || 1.second
84
78
  status = 0
@@ -88,17 +82,17 @@ module Eye::System
88
82
  status = st.exitstatus || st.termsig
89
83
  end
90
84
 
91
- { pid: pid, exitstatus: status }
85
+ {:pid => pid, :exitstatus => status}
92
86
 
93
87
  rescue Timeout::Error => ex
94
88
  if pid
95
89
  warn "[#{cfg[:name]}] sending :KILL signal to <#{pid}> due to timeout (#{timeout}s)"
96
90
  send_signal(pid, 9)
97
91
  end
98
- { error: ex }
92
+ {:error => ex}
99
93
 
100
94
  rescue Errno::ENOENT, Errno::EACCES => ex
101
- { error: ex }
95
+ {:error => ex}
102
96
 
103
97
  ensure
104
98
  Process.detach(pid) if pid
@@ -133,13 +127,12 @@ module Eye::System
133
127
  def prepare_env(config = {})
134
128
  env = {}
135
129
 
136
- (config[:environment] || {}).each do |k, v|
130
+ (config[:environment] || {}).each do |k,v|
137
131
  env[k.to_s] = v && v.to_s
138
132
  end
139
133
 
140
134
  env
141
135
  end
142
-
143
136
  end
144
137
 
145
138
  end