eye 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +31 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +132 -0
- data/Rakefile +18 -0
- data/bin/eye +282 -0
- data/bin/loader_eye +56 -0
- data/examples/processes/em.rb +56 -0
- data/examples/processes/forking.rb +20 -0
- data/examples/processes/sample.rb +144 -0
- data/examples/rbenv.eye +11 -0
- data/examples/test.eye +65 -0
- data/examples/unicorn.eye +29 -0
- data/eye.gemspec +37 -0
- data/lib/eye.rb +25 -0
- data/lib/eye/application.rb +65 -0
- data/lib/eye/checker.rb +118 -0
- data/lib/eye/checker/cpu.rb +27 -0
- data/lib/eye/checker/file_ctime.rb +29 -0
- data/lib/eye/checker/file_size.rb +38 -0
- data/lib/eye/checker/http.rb +94 -0
- data/lib/eye/checker/memory.rb +27 -0
- data/lib/eye/checker/socket.rb +148 -0
- data/lib/eye/checker/validation.rb +49 -0
- data/lib/eye/child_process.rb +75 -0
- data/lib/eye/client.rb +32 -0
- data/lib/eye/control.rb +2 -0
- data/lib/eye/controller.rb +43 -0
- data/lib/eye/controller/commands.rb +64 -0
- data/lib/eye/controller/helpers.rb +61 -0
- data/lib/eye/controller/load.rb +224 -0
- data/lib/eye/controller/send_command.rb +88 -0
- data/lib/eye/controller/status.rb +136 -0
- data/lib/eye/dsl.rb +52 -0
- data/lib/eye/dsl/application_opts.rb +33 -0
- data/lib/eye/dsl/chain.rb +12 -0
- data/lib/eye/dsl/child_process_opts.rb +7 -0
- data/lib/eye/dsl/config_opts.rb +11 -0
- data/lib/eye/dsl/group_opts.rb +27 -0
- data/lib/eye/dsl/helpers.rb +12 -0
- data/lib/eye/dsl/main.rb +58 -0
- data/lib/eye/dsl/opts.rb +88 -0
- data/lib/eye/dsl/process_opts.rb +21 -0
- data/lib/eye/dsl/pure_opts.rb +132 -0
- data/lib/eye/dsl/validate.rb +41 -0
- data/lib/eye/group.rb +125 -0
- data/lib/eye/group/chain.rb +68 -0
- data/lib/eye/io/unix_server.rb +44 -0
- data/lib/eye/io/unix_socket.rb +39 -0
- data/lib/eye/loader.rb +13 -0
- data/lib/eye/logger.rb +80 -0
- data/lib/eye/process.rb +83 -0
- data/lib/eye/process/child.rb +61 -0
- data/lib/eye/process/commands.rb +256 -0
- data/lib/eye/process/config.rb +70 -0
- data/lib/eye/process/controller.rb +72 -0
- data/lib/eye/process/data.rb +46 -0
- data/lib/eye/process/monitor.rb +97 -0
- data/lib/eye/process/notify.rb +17 -0
- data/lib/eye/process/scheduler.rb +50 -0
- data/lib/eye/process/states.rb +92 -0
- data/lib/eye/process/states_history.rb +62 -0
- data/lib/eye/process/system.rb +60 -0
- data/lib/eye/process/trigger.rb +32 -0
- data/lib/eye/process/watchers.rb +67 -0
- data/lib/eye/server.rb +51 -0
- data/lib/eye/settings.rb +35 -0
- data/lib/eye/system.rb +145 -0
- data/lib/eye/system_resources.rb +83 -0
- data/lib/eye/trigger.rb +53 -0
- data/lib/eye/trigger/flapping.rb +24 -0
- data/lib/eye/utils.rb +5 -0
- data/lib/eye/utils/alive_array.rb +31 -0
- data/lib/eye/utils/celluloid_chain.rb +51 -0
- data/lib/eye/utils/leak_19.rb +7 -0
- data/lib/eye/utils/tail.rb +20 -0
- data/spec/checker/cpu_spec.rb +58 -0
- data/spec/checker/file_ctime_spec.rb +34 -0
- data/spec/checker/file_size_spec.rb +107 -0
- data/spec/checker/http_spec.rb +109 -0
- data/spec/checker/memory_spec.rb +64 -0
- data/spec/checker/socket_spec.rb +116 -0
- data/spec/checker_spec.rb +188 -0
- data/spec/child_process/child_process_spec.rb +46 -0
- data/spec/client_server_spec.rb +34 -0
- data/spec/controller/commands_spec.rb +92 -0
- data/spec/controller/controller_spec.rb +133 -0
- data/spec/controller/find_objects_spec.rb +150 -0
- data/spec/controller/group_spec.rb +110 -0
- data/spec/controller/intergration_spec.rb +327 -0
- data/spec/controller/load_spec.rb +326 -0
- data/spec/controller/races_spec.rb +70 -0
- data/spec/controller/stop_on_delete_spec.rb +157 -0
- data/spec/dsl/chain_spec.rb +140 -0
- data/spec/dsl/checks_spec.rb +202 -0
- data/spec/dsl/config_spec.rb +44 -0
- data/spec/dsl/dsl_spec.rb +73 -0
- data/spec/dsl/getter_spec.rb +223 -0
- data/spec/dsl/integration_spec.rb +311 -0
- data/spec/dsl/load_spec.rb +52 -0
- data/spec/dsl/process_spec.rb +330 -0
- data/spec/dsl/sub_procs_spec.rb +93 -0
- data/spec/dsl/with_server_spec.rb +104 -0
- data/spec/example/em.rb +57 -0
- data/spec/example/forking.rb +20 -0
- data/spec/example/sample.rb +154 -0
- data/spec/fixtures/dsl/0.rb +8 -0
- data/spec/fixtures/dsl/0a.rb +8 -0
- data/spec/fixtures/dsl/0c.rb +8 -0
- data/spec/fixtures/dsl/1.rb +5 -0
- data/spec/fixtures/dsl/bad.eye +6 -0
- data/spec/fixtures/dsl/configs/1.eye +3 -0
- data/spec/fixtures/dsl/configs/2.eye +1 -0
- data/spec/fixtures/dsl/configs/3.eye +1 -0
- data/spec/fixtures/dsl/configs/4.eye +3 -0
- data/spec/fixtures/dsl/empty.eye +20 -0
- data/spec/fixtures/dsl/include_test.eye +5 -0
- data/spec/fixtures/dsl/include_test/1.rb +6 -0
- data/spec/fixtures/dsl/include_test/ha.rb +4 -0
- data/spec/fixtures/dsl/include_test2.eye +5 -0
- data/spec/fixtures/dsl/integration.eye +30 -0
- data/spec/fixtures/dsl/integration2.eye +32 -0
- data/spec/fixtures/dsl/integration_locks.eye +30 -0
- data/spec/fixtures/dsl/integration_sor.eye +32 -0
- data/spec/fixtures/dsl/integration_sor2.eye +27 -0
- data/spec/fixtures/dsl/integration_sor3.eye +32 -0
- data/spec/fixtures/dsl/load.eye +25 -0
- data/spec/fixtures/dsl/load2.eye +7 -0
- data/spec/fixtures/dsl/load2_dup2.eye +13 -0
- data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
- data/spec/fixtures/dsl/load3.eye +10 -0
- data/spec/fixtures/dsl/load4.eye +7 -0
- data/spec/fixtures/dsl/load5.eye +8 -0
- data/spec/fixtures/dsl/load6.eye +17 -0
- data/spec/fixtures/dsl/load_dubls.eye +36 -0
- data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
- data/spec/fixtures/dsl/load_error.eye +5 -0
- data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_int.eye +8 -0
- data/spec/fixtures/dsl/load_int2.eye +13 -0
- data/spec/fixtures/dsl/load_logger.eye +26 -0
- data/spec/fixtures/dsl/load_logger2.eye +3 -0
- data/spec/fixtures/dsl/long_load.eye +5 -0
- data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
- data/spec/fixtures/dsl/subfolder2.eye +9 -0
- data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
- data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
- data/spec/fixtures/dsl/subfolder3.eye +8 -0
- data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
- data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
- data/spec/fixtures/dsl/subfolder4.eye +6 -0
- data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
- data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
- data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
- data/spec/mock_spec.rb +32 -0
- data/spec/process/checks/child_checks_spec.rb +79 -0
- data/spec/process/checks/cpu_spec.rb +114 -0
- data/spec/process/checks/ctime_spec.rb +43 -0
- data/spec/process/checks/fsize_spec.rb +22 -0
- data/spec/process/checks/http_spec.rb +52 -0
- data/spec/process/checks/intergration_spec.rb +32 -0
- data/spec/process/checks/memory_spec.rb +113 -0
- data/spec/process/child_process_spec.rb +125 -0
- data/spec/process/config_spec.rb +75 -0
- data/spec/process/controller_spec.rb +173 -0
- data/spec/process/monitoring_spec.rb +180 -0
- data/spec/process/restart_spec.rb +174 -0
- data/spec/process/scheduler_spec.rb +150 -0
- data/spec/process/start_spec.rb +261 -0
- data/spec/process/states_history_spec.rb +118 -0
- data/spec/process/stop_spec.rb +150 -0
- data/spec/process/system_spec.rb +100 -0
- data/spec/process/triggers/flapping_spec.rb +81 -0
- data/spec/process/update_config_spec.rb +63 -0
- data/spec/spec_helper.rb +120 -0
- data/spec/support/rr_celluloid.rb +36 -0
- data/spec/support/scheduler_hack.rb +16 -0
- data/spec/support/spec_support.rb +164 -0
- data/spec/system_resources_spec.rb +59 -0
- data/spec/system_spec.rb +170 -0
- data/spec/utils/alive_array_spec.rb +50 -0
- data/spec/utils/celluloid_chain_spec.rb +82 -0
- data/spec/utils/tail_spec.rb +21 -0
- metadata +558 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
module Eye::Process::Config
|
2
|
+
|
3
|
+
DEFAULTS = {
|
4
|
+
:keep_alive => true, # restart when crushed
|
5
|
+
:check_alive_period => 5.seconds,
|
6
|
+
|
7
|
+
:start_timeout => 15.seconds,
|
8
|
+
:stop_timeout => 10.seconds,
|
9
|
+
:restart_timeout => 10.seconds,
|
10
|
+
|
11
|
+
:start_grace => 2.5.seconds,
|
12
|
+
:stop_grace => 0.5.seconds,
|
13
|
+
:restart_grace => 0.5.seconds,
|
14
|
+
|
15
|
+
:daemonize => false,
|
16
|
+
:auto_start => true, # auto start on monitor action
|
17
|
+
|
18
|
+
:childs_update_period => 30.seconds
|
19
|
+
}
|
20
|
+
|
21
|
+
def prepare_config(new_config)
|
22
|
+
h = DEFAULTS.merge(new_config)
|
23
|
+
h[:pid_file_ex] = Eye::System.normalized_file(h[:pid_file], h[:working_dir]) if h[:pid_file]
|
24
|
+
h[:checks] = {} if h[:checks].blank?
|
25
|
+
h[:triggers] = {} if h[:triggers].blank?
|
26
|
+
h[:childs_update_period] = h[:monitor_children][:childs_update_period] if h[:monitor_children] && h[:monitor_children][:childs_update_period]
|
27
|
+
|
28
|
+
# check speedy flapping by default
|
29
|
+
if h[:triggers].blank? || !h[:triggers][:flapping]
|
30
|
+
h[:triggers] ||= {}
|
31
|
+
h[:triggers][:flapping] = {:type => :flapping, :times => 10, :within => 10.seconds}
|
32
|
+
end
|
33
|
+
|
34
|
+
h[:stdout] = Eye::System.normalized_file(h[:stdout], h[:working_dir]) if h[:stdout]
|
35
|
+
h[:stderr] = Eye::System.normalized_file(h[:stderr], h[:working_dir]) if h[:stderr]
|
36
|
+
|
37
|
+
h
|
38
|
+
end
|
39
|
+
|
40
|
+
def c(name)
|
41
|
+
@config[name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def [](name)
|
45
|
+
@config[name]
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_config(new_config = {})
|
49
|
+
new_config = prepare_config(new_config)
|
50
|
+
@config = new_config
|
51
|
+
@full_name = nil
|
52
|
+
|
53
|
+
debug "update config to: #{@config.inspect}"
|
54
|
+
|
55
|
+
remove_triggers
|
56
|
+
add_triggers
|
57
|
+
|
58
|
+
if up?
|
59
|
+
# rebuild checks for this process
|
60
|
+
from_up; on_up
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# is pid_file under Eye::Process control, or not
|
65
|
+
def control_pid?
|
66
|
+
return self[:control_pid] unless self[:control_pid].nil?
|
67
|
+
!!self[:daemonize]
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Eye::Process::Controller
|
2
|
+
|
3
|
+
def send_command(command, *args)
|
4
|
+
schedule command, *args, "#{command} by user"
|
5
|
+
end
|
6
|
+
|
7
|
+
def start
|
8
|
+
res = if set_pid_from_file
|
9
|
+
if process_realy_running?
|
10
|
+
info "process from pid_file(#{self.pid}) found and already running, so :up"
|
11
|
+
switch :already_running
|
12
|
+
:ok
|
13
|
+
else
|
14
|
+
info "pid_file found, but process in pid_file(#{self.pid}) not found, starting..."
|
15
|
+
start_process
|
16
|
+
end
|
17
|
+
else
|
18
|
+
info 'pid_file not found, so starting process...'
|
19
|
+
start_process
|
20
|
+
end
|
21
|
+
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop
|
26
|
+
stop_process
|
27
|
+
switch :unmonitoring
|
28
|
+
end
|
29
|
+
|
30
|
+
def restart
|
31
|
+
restart_process
|
32
|
+
end
|
33
|
+
|
34
|
+
def monitor
|
35
|
+
if self[:auto_start]
|
36
|
+
start
|
37
|
+
else
|
38
|
+
if try_update_pid_from_file
|
39
|
+
info "process from pid_file(#{self.pid}) found and already running, so :up"
|
40
|
+
switch :already_running
|
41
|
+
else
|
42
|
+
warn "process not found, so :unmonitor"
|
43
|
+
schedule :unmonitor, 'not found'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def unmonitor
|
49
|
+
switch :unmonitoring
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete
|
53
|
+
if self[:stop_on_delete]
|
54
|
+
info 'process has stop_on_delete option, so sync-stop it first'
|
55
|
+
stop
|
56
|
+
end
|
57
|
+
|
58
|
+
remove_watchers
|
59
|
+
remove_childs
|
60
|
+
remove_triggers
|
61
|
+
|
62
|
+
terminate
|
63
|
+
end
|
64
|
+
|
65
|
+
def signal(sig = 0)
|
66
|
+
if self.pid
|
67
|
+
res = send_signal(sig)
|
68
|
+
info "send signal #{sig} to #{self.pid} = #{res}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Eye::Process::Data
|
2
|
+
|
3
|
+
# logger tag
|
4
|
+
def full_name
|
5
|
+
@full_name ||= [self[:application], (self[:group] == '__default__') ? nil : self[:group], self[:name]].compact.join(':')
|
6
|
+
end
|
7
|
+
|
8
|
+
def status_data(debug = false)
|
9
|
+
p_st = self_status_data(debug)
|
10
|
+
|
11
|
+
if childs.present?
|
12
|
+
p_st.merge(:subtree => Eye::Utils::AliveArray.new(childs.values).map{|c| c.status_data(debug) } )
|
13
|
+
elsif self[:monitor_children] && self.up?
|
14
|
+
p_st.merge(:subtree => [{name: '=loading childs='}])
|
15
|
+
else
|
16
|
+
# common state
|
17
|
+
p_st
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self_status_data(debug = false)
|
22
|
+
h = { name: name, state: state,
|
23
|
+
type: (self.class == Eye::ChildProcess ? :child_process : :process),
|
24
|
+
resources: Eye::SystemResources.resources(pid) }
|
25
|
+
|
26
|
+
if @states_history
|
27
|
+
h.merge!( state_changed_at: @states_history.last[:at],
|
28
|
+
state_reason: @states_history.last[:reason] )
|
29
|
+
end
|
30
|
+
|
31
|
+
h.merge!(debug: debug_data) if debug
|
32
|
+
h.merge!(current_command: current_scheduled_command) if current_scheduled_command
|
33
|
+
|
34
|
+
h
|
35
|
+
end
|
36
|
+
|
37
|
+
def debug_data
|
38
|
+
{ queue: scheduler_actions_list, watchers: @watchers.keys }
|
39
|
+
end
|
40
|
+
|
41
|
+
def sub_object?(obj)
|
42
|
+
# we not recognize childs
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Eye::Process::Monitor
|
2
|
+
|
3
|
+
private
|
4
|
+
|
5
|
+
def check_alive_with_refresh_pid_if_needed
|
6
|
+
if process_realy_running?
|
7
|
+
return true
|
8
|
+
|
9
|
+
else
|
10
|
+
warn 'process not realy running'
|
11
|
+
try_update_pid_from_file
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def try_update_pid_from_file
|
16
|
+
# if pid file was rewrited
|
17
|
+
newpid = load_pid_from_file
|
18
|
+
if newpid != self.pid
|
19
|
+
info "process changed pid to #{newpid}, updating..." if self.pid
|
20
|
+
self.pid = newpid
|
21
|
+
|
22
|
+
if process_realy_running?
|
23
|
+
return true
|
24
|
+
else
|
25
|
+
warn "process with new_pid #{newpid} not found"
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
else
|
29
|
+
debug 'process not found'
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
REWRITE_FACKUP_PIDFILE_PERIOD = 2.minutes
|
35
|
+
|
36
|
+
def check_alive
|
37
|
+
if up?
|
38
|
+
|
39
|
+
# check that process runned
|
40
|
+
unless process_realy_running?
|
41
|
+
warn 'check_alive: process not found'
|
42
|
+
notify :warn, 'crushed!'
|
43
|
+
switch :crushed
|
44
|
+
else
|
45
|
+
# check that pid_file still here
|
46
|
+
ppid = failsafe_load_pid
|
47
|
+
|
48
|
+
if ppid != self.pid
|
49
|
+
msg = "check_alive: pid_file(#{self[:pid_file]}) changes by itself (#{self.pid}) => (#{ppid})"
|
50
|
+
if control_pid?
|
51
|
+
msg += ", not correct, pid_file is under eye control, so rewrited back #{self.pid}"
|
52
|
+
save_pid_to_file rescue msg += ', (Can`t rewrite pid_file O_o)'
|
53
|
+
else
|
54
|
+
if ppid == nil
|
55
|
+
msg += ', rewrited because empty'
|
56
|
+
save_pid_to_file rescue msg += ', (Can`t rewrite pid_file O_o)'
|
57
|
+
elsif (Time.now - pid_file_ctime > REWRITE_FACKUP_PIDFILE_PERIOD)
|
58
|
+
msg += ", > #{REWRITE_FACKUP_PIDFILE_PERIOD.inspect} ago, so rewrited (even if pid_file not under eye control)"
|
59
|
+
save_pid_to_file rescue msg += ', (Can`t rewrite pid_file O_o)'
|
60
|
+
else
|
61
|
+
msg += ', not under eye control, so ignored'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
warn msg
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def failsafe_load_pid
|
72
|
+
pid = load_pid_from_file
|
73
|
+
|
74
|
+
if !pid
|
75
|
+
# this is can be symlink changed case
|
76
|
+
sleep 0.1
|
77
|
+
pid = load_pid_from_file
|
78
|
+
end
|
79
|
+
|
80
|
+
pid
|
81
|
+
end
|
82
|
+
|
83
|
+
def check_crush
|
84
|
+
if down?
|
85
|
+
if self[:keep_alive] && !@flapping
|
86
|
+
warn 'check crushed: process is down'
|
87
|
+
schedule :start, 'crushed'
|
88
|
+
else
|
89
|
+
warn 'check crushed: process is down, and flapping happens (or not keep_alive option)'
|
90
|
+
schedule :unmonitor, 'flapping'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
public :check_crush # bug of celluloid 0.12
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Eye::Process::Notify
|
2
|
+
|
3
|
+
# notify to user:
|
4
|
+
# 1) process crushed by itself, and we restart it
|
5
|
+
# 2) checker fire to restart process +
|
6
|
+
# 3) flapping + switch to unmonitored
|
7
|
+
|
8
|
+
# level = [:warn, :crit]
|
9
|
+
|
10
|
+
# TODO: add mail, jabber here
|
11
|
+
def notify(level, msg)
|
12
|
+
if level != :warn
|
13
|
+
warn "!!!!!!!! NOTIFY: #{level}, #{msg} !!!!!!!!!!!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Eye::Process::Scheduler
|
2
|
+
|
3
|
+
# ex: schedule :update_config, config, "reason: update_config"
|
4
|
+
def schedule(command, *args, &block)
|
5
|
+
if scheduler.alive?
|
6
|
+
reason = if args.present? && [String, Symbol].include?(args[-1].class)
|
7
|
+
args.pop
|
8
|
+
end
|
9
|
+
|
10
|
+
info "schedule :#{command} (#{reason})"
|
11
|
+
scheduler.add_wo_dups(:scheduled_action, command, {:args => args, :reason => reason}, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def scheduled_action(command, h = {}, &block)
|
16
|
+
reason = h.delete(:reason)
|
17
|
+
info "=> #{command} #{h[:args].present? ? "#{h[:args]*',' }" : nil}(#{reason})"
|
18
|
+
|
19
|
+
@current_scheduled_command = command
|
20
|
+
@last_scheduled_command = command
|
21
|
+
@last_scheduled_reason = reason
|
22
|
+
@last_scheduled_at = Time.now
|
23
|
+
|
24
|
+
send(command, *h[:args], &block)
|
25
|
+
@current_scheduled_command = nil
|
26
|
+
info "<= #{command}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def scheduler_actions_list
|
30
|
+
scheduler.list.map{|c| c[:args].first rescue nil }.compact
|
31
|
+
end
|
32
|
+
|
33
|
+
def finalize
|
34
|
+
remove_scheduler
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :current_scheduled_command
|
38
|
+
attr_accessor :last_scheduled_command, :last_scheduled_reason, :last_scheduled_at
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def remove_scheduler
|
43
|
+
@scheduler.terminate if @scheduler && @scheduler.alive?
|
44
|
+
end
|
45
|
+
|
46
|
+
def scheduler
|
47
|
+
@scheduler ||= Eye::Utils::CelluloidChain.new(current_actor)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
gem 'state_machine'
|
2
|
+
require 'state_machine'
|
3
|
+
|
4
|
+
class Eye::Process
|
5
|
+
|
6
|
+
# do transition
|
7
|
+
def switch(name, reason = nil)
|
8
|
+
@state_reason = reason || last_scheduled_reason
|
9
|
+
self.send("#{name}!")
|
10
|
+
end
|
11
|
+
|
12
|
+
state_machine :state, :initial => :unmonitored do
|
13
|
+
state :unmonitored, :up, :down
|
14
|
+
state :starting, :stopping, :restarting
|
15
|
+
|
16
|
+
event :starting do
|
17
|
+
transition [:unmonitored, :down] => :starting
|
18
|
+
end
|
19
|
+
|
20
|
+
event :already_running do
|
21
|
+
transition [:unmonitored, :down, :up] => :up
|
22
|
+
end
|
23
|
+
|
24
|
+
event :started do
|
25
|
+
transition :starting => :up
|
26
|
+
end
|
27
|
+
|
28
|
+
event :crushed do
|
29
|
+
transition [:starting, :restarting, :up] => :down
|
30
|
+
end
|
31
|
+
|
32
|
+
event :stopping do
|
33
|
+
transition [:up, :restarting] => :stopping
|
34
|
+
end
|
35
|
+
|
36
|
+
event :stopped do
|
37
|
+
transition :stopping => :down
|
38
|
+
end
|
39
|
+
|
40
|
+
event :cant_kill do
|
41
|
+
transition :stopping => :up
|
42
|
+
end
|
43
|
+
|
44
|
+
event :restarting do
|
45
|
+
transition [:unmonitored, :up, :down] => :restarting
|
46
|
+
end
|
47
|
+
|
48
|
+
event :restarted do
|
49
|
+
transition :restarting => :up
|
50
|
+
end
|
51
|
+
|
52
|
+
event :unmonitoring do
|
53
|
+
transition any => :unmonitored
|
54
|
+
end
|
55
|
+
|
56
|
+
after_transition :on => :crushed, :do => :on_crushed
|
57
|
+
after_transition any => :unmonitored, :do => :on_unmonitored
|
58
|
+
after_transition any-:up => :up, :do => :on_up
|
59
|
+
after_transition :up => any-:up, :do => :from_up
|
60
|
+
after_transition any => any, :do => :log_transition
|
61
|
+
after_transition any => any, :do => :upd_for_triggers
|
62
|
+
end
|
63
|
+
|
64
|
+
def on_crushed
|
65
|
+
schedule :check_crush, 'crushed'
|
66
|
+
end
|
67
|
+
|
68
|
+
def on_unmonitored
|
69
|
+
self.flapping = false
|
70
|
+
self.pid = nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def on_up
|
74
|
+
add_watchers
|
75
|
+
add_childs
|
76
|
+
end
|
77
|
+
|
78
|
+
def from_up
|
79
|
+
remove_watchers
|
80
|
+
remove_childs
|
81
|
+
end
|
82
|
+
|
83
|
+
def log_transition(transition)
|
84
|
+
@states_history.push transition.to_name, @state_reason
|
85
|
+
info "switch :#{transition.event} [:#{transition.from_name} => :#{transition.to_name}] #{@state_reason ? "(#{@state_reason})" : nil}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def upd_for_triggers(transition)
|
89
|
+
check_triggers
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|