eye 0.8.celluloid15 → 0.8.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -5
- data/CHANGES.md +3 -7
- data/README.md +2 -5
- data/Rakefile +6 -6
- data/bin/leye +4 -9
- data/bin/loader_eye +15 -14
- data/examples/delayed_job.eye +3 -3
- data/examples/dependency.eye +11 -10
- data/examples/notify.eye +4 -3
- data/examples/plugin/main.eye +5 -5
- data/examples/plugin/plugin.rb +2 -10
- data/examples/process_thin.rb +8 -8
- data/examples/processes/em.rb +12 -18
- data/examples/processes/forking.rb +5 -5
- data/examples/processes/sample.rb +44 -46
- data/examples/puma.eye +8 -9
- data/examples/rbenv.eye +5 -5
- data/examples/sidekiq.eye +3 -3
- data/examples/stress_test.eye +4 -4
- data/examples/syslog.eye +1 -1
- data/examples/test.eye +2 -1
- data/examples/thin-farm.eye +8 -7
- data/examples/triggers.eye +15 -13
- data/examples/unicorn.eye +13 -12
- data/eye.gemspec +14 -16
- data/lib/eye.rb +3 -2
- data/lib/eye/application.rb +6 -5
- data/lib/eye/checker.rb +25 -44
- data/lib/eye/checker/children_count.rb +1 -1
- data/lib/eye/checker/file_ctime.rb +1 -1
- data/lib/eye/checker/http.rb +15 -13
- data/lib/eye/checker/nop.rb +0 -1
- data/lib/eye/checker/socket.rb +63 -60
- data/lib/eye/checker/ssl_socket.rb +5 -5
- data/lib/eye/child_process.rb +4 -6
- data/lib/eye/cli.rb +46 -74
- data/lib/eye/cli/commands.rb +5 -4
- data/lib/eye/cli/render.rb +41 -61
- data/lib/eye/cli/server.rb +16 -19
- data/lib/eye/client.rb +0 -1
- data/lib/eye/config.rb +33 -36
- data/lib/eye/controller.rb +3 -2
- data/lib/eye/controller/commands.rb +1 -1
- data/lib/eye/controller/helpers.rb +2 -2
- data/lib/eye/controller/load.rb +17 -19
- data/lib/eye/controller/options.rb +5 -1
- data/lib/eye/controller/send_command.rb +23 -21
- data/lib/eye/controller/status.rb +15 -17
- data/lib/eye/dsl.rb +1 -6
- data/lib/eye/dsl/application_opts.rb +3 -4
- data/lib/eye/dsl/chain.rb +2 -2
- data/lib/eye/dsl/child_process_opts.rb +3 -3
- data/lib/eye/dsl/config_opts.rb +7 -7
- data/lib/eye/dsl/group_opts.rb +3 -3
- data/lib/eye/dsl/helpers.rb +1 -1
- data/lib/eye/dsl/main.rb +3 -4
- data/lib/eye/dsl/opts.rb +28 -31
- data/lib/eye/dsl/process_opts.rb +7 -13
- data/lib/eye/dsl/pure_opts.rb +9 -13
- data/lib/eye/dsl/validation.rb +35 -48
- data/lib/eye/group.rb +8 -23
- data/lib/eye/group/chain.rb +6 -6
- data/lib/eye/loader.rb +3 -3
- data/lib/eye/local.rb +4 -9
- data/lib/eye/logger.rb +4 -11
- data/lib/eye/notify.rb +6 -10
- data/lib/eye/notify/jabber.rb +1 -1
- data/lib/eye/notify/mail.rb +2 -2
- data/lib/eye/notify/slack.rb +3 -4
- data/lib/eye/process.rb +0 -2
- data/lib/eye/process/children.rb +4 -4
- data/lib/eye/process/commands.rb +39 -38
- data/lib/eye/process/config.rb +16 -22
- data/lib/eye/process/controller.rb +19 -5
- data/lib/eye/process/data.rb +9 -11
- data/lib/eye/process/monitor.rb +76 -86
- data/lib/eye/process/notify.rb +10 -10
- data/lib/eye/process/scheduler.rb +31 -36
- data/lib/eye/process/states.rb +5 -7
- data/lib/eye/process/states_history.rb +3 -9
- data/lib/eye/process/system.rb +20 -35
- data/lib/eye/process/trigger.rb +5 -1
- data/lib/eye/process/watchers.rb +9 -12
- data/lib/eye/reason.rb +1 -4
- data/lib/eye/server.rb +1 -2
- data/lib/eye/system.rb +15 -22
- data/lib/eye/system_resources.rb +9 -18
- data/lib/eye/trigger.rb +16 -18
- data/lib/eye/trigger/check_dependency.rb +4 -7
- data/lib/eye/trigger/flapping.rb +7 -24
- data/lib/eye/trigger/starting_guard.rb +6 -7
- data/lib/eye/trigger/stop_children.rb +2 -2
- data/lib/eye/trigger/transition.rb +1 -1
- data/lib/eye/trigger/wait_dependency.rb +2 -3
- data/lib/eye/utils.rb +3 -4
- data/lib/eye/utils/alive_array.rb +4 -9
- data/lib/eye/utils/celluloid_chain.rb +10 -12
- data/lib/eye/utils/leak_19.rb +10 -0
- data/lib/eye/utils/mini_active_support.rb +16 -16
- data/lib/eye/utils/pmap.rb +0 -2
- data/lib/eye/utils/tail.rb +2 -2
- metadata +8 -39
- data/.rubocop.yml +0 -141
- data/examples/custom_check.eye +0 -24
- data/examples/custom_trigger.eye +0 -30
- data/examples/leye_example/Eyefile +0 -10
data/lib/eye/process/notify.rb
CHANGED
@@ -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 = {
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
42
|
-
info "=> #{command} #{h[:args].present? ? "#{h[:args]
|
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], &
|
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
|
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
|
data/lib/eye/process/states.rb
CHANGED
@@ -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, :
|
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
|
64
|
-
after_transition :up => any
|
62
|
+
after_transition any-:up => :up, :do => :add_watchers
|
63
|
+
after_transition :up => any-:up, :do => :remove_watchers
|
65
64
|
|
66
|
-
after_transition any
|
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})"
|
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
|
7
|
+
self.map{|c| c[:state] }
|
9
8
|
end
|
10
9
|
|
11
|
-
def states_for_period(period, from_time = nil
|
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
|
-
|
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
|
data/lib/eye/process/system.rb
CHANGED
@@ -3,7 +3,16 @@ require 'timeout'
|
|
3
3
|
module Eye::Process::System
|
4
4
|
|
5
5
|
def load_pid_from_file
|
6
|
-
File.
|
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
|
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.
|
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, &
|
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
|
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 = {
|
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
|
-
|
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
|
106
|
+
pid
|
122
107
|
end
|
123
108
|
|
124
109
|
def failsafe_save_pid
|
data/lib/eye/process/trigger.rb
CHANGED
data/lib/eye/process/watchers.rb
CHANGED
@@ -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
|
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] ||= {
|
45
|
+
@watchers[type] ||= {:timer => timer, :subject => subject}
|
52
46
|
end
|
53
47
|
|
54
48
|
def start_checkers
|
55
|
-
self[:checks].each
|
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
|
-
|
66
|
-
|
60
|
+
unless subject.check
|
61
|
+
return unless up?
|
62
|
+
subject.fire
|
63
|
+
end
|
67
64
|
end
|
68
65
|
|
69
66
|
end
|
data/lib/eye/reason.rb
CHANGED
data/lib/eye/server.rb
CHANGED
data/lib/eye/system.rb
CHANGED
@@ -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
|
-
{
|
17
|
+
{:result => res}
|
20
18
|
rescue => ex
|
21
|
-
{
|
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
|
-
|
29
|
-
|
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
|
-
{
|
42
|
+
{:result => :ok}
|
49
43
|
else
|
50
|
-
{
|
44
|
+
{:error => Exception.new('no_pid')}
|
51
45
|
end
|
52
46
|
|
53
47
|
rescue => ex
|
54
|
-
{
|
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
|
58
|
+
pid = ::Process::spawn(prepare_env(cfg), *Shellwords.shellwords(cmd), spawn_options(cfg))
|
65
59
|
|
66
|
-
{
|
60
|
+
{:pid => pid, :exitstatus => 0}
|
67
61
|
|
68
62
|
rescue Errno::ENOENT, Errno::EACCES => ex
|
69
|
-
{
|
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
|
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
|
-
{
|
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
|
-
{
|
92
|
+
{:error => ex}
|
99
93
|
|
100
94
|
rescue Errno::ENOENT, Errno::EACCES => ex
|
101
|
-
{
|
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,
|
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
|