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.
Files changed (190) hide show
  1. data/.gitignore +31 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +132 -0
  6. data/Rakefile +18 -0
  7. data/bin/eye +282 -0
  8. data/bin/loader_eye +56 -0
  9. data/examples/processes/em.rb +56 -0
  10. data/examples/processes/forking.rb +20 -0
  11. data/examples/processes/sample.rb +144 -0
  12. data/examples/rbenv.eye +11 -0
  13. data/examples/test.eye +65 -0
  14. data/examples/unicorn.eye +29 -0
  15. data/eye.gemspec +37 -0
  16. data/lib/eye.rb +25 -0
  17. data/lib/eye/application.rb +65 -0
  18. data/lib/eye/checker.rb +118 -0
  19. data/lib/eye/checker/cpu.rb +27 -0
  20. data/lib/eye/checker/file_ctime.rb +29 -0
  21. data/lib/eye/checker/file_size.rb +38 -0
  22. data/lib/eye/checker/http.rb +94 -0
  23. data/lib/eye/checker/memory.rb +27 -0
  24. data/lib/eye/checker/socket.rb +148 -0
  25. data/lib/eye/checker/validation.rb +49 -0
  26. data/lib/eye/child_process.rb +75 -0
  27. data/lib/eye/client.rb +32 -0
  28. data/lib/eye/control.rb +2 -0
  29. data/lib/eye/controller.rb +43 -0
  30. data/lib/eye/controller/commands.rb +64 -0
  31. data/lib/eye/controller/helpers.rb +61 -0
  32. data/lib/eye/controller/load.rb +224 -0
  33. data/lib/eye/controller/send_command.rb +88 -0
  34. data/lib/eye/controller/status.rb +136 -0
  35. data/lib/eye/dsl.rb +52 -0
  36. data/lib/eye/dsl/application_opts.rb +33 -0
  37. data/lib/eye/dsl/chain.rb +12 -0
  38. data/lib/eye/dsl/child_process_opts.rb +7 -0
  39. data/lib/eye/dsl/config_opts.rb +11 -0
  40. data/lib/eye/dsl/group_opts.rb +27 -0
  41. data/lib/eye/dsl/helpers.rb +12 -0
  42. data/lib/eye/dsl/main.rb +58 -0
  43. data/lib/eye/dsl/opts.rb +88 -0
  44. data/lib/eye/dsl/process_opts.rb +21 -0
  45. data/lib/eye/dsl/pure_opts.rb +132 -0
  46. data/lib/eye/dsl/validate.rb +41 -0
  47. data/lib/eye/group.rb +125 -0
  48. data/lib/eye/group/chain.rb +68 -0
  49. data/lib/eye/io/unix_server.rb +44 -0
  50. data/lib/eye/io/unix_socket.rb +39 -0
  51. data/lib/eye/loader.rb +13 -0
  52. data/lib/eye/logger.rb +80 -0
  53. data/lib/eye/process.rb +83 -0
  54. data/lib/eye/process/child.rb +61 -0
  55. data/lib/eye/process/commands.rb +256 -0
  56. data/lib/eye/process/config.rb +70 -0
  57. data/lib/eye/process/controller.rb +72 -0
  58. data/lib/eye/process/data.rb +46 -0
  59. data/lib/eye/process/monitor.rb +97 -0
  60. data/lib/eye/process/notify.rb +17 -0
  61. data/lib/eye/process/scheduler.rb +50 -0
  62. data/lib/eye/process/states.rb +92 -0
  63. data/lib/eye/process/states_history.rb +62 -0
  64. data/lib/eye/process/system.rb +60 -0
  65. data/lib/eye/process/trigger.rb +32 -0
  66. data/lib/eye/process/watchers.rb +67 -0
  67. data/lib/eye/server.rb +51 -0
  68. data/lib/eye/settings.rb +35 -0
  69. data/lib/eye/system.rb +145 -0
  70. data/lib/eye/system_resources.rb +83 -0
  71. data/lib/eye/trigger.rb +53 -0
  72. data/lib/eye/trigger/flapping.rb +24 -0
  73. data/lib/eye/utils.rb +5 -0
  74. data/lib/eye/utils/alive_array.rb +31 -0
  75. data/lib/eye/utils/celluloid_chain.rb +51 -0
  76. data/lib/eye/utils/leak_19.rb +7 -0
  77. data/lib/eye/utils/tail.rb +20 -0
  78. data/spec/checker/cpu_spec.rb +58 -0
  79. data/spec/checker/file_ctime_spec.rb +34 -0
  80. data/spec/checker/file_size_spec.rb +107 -0
  81. data/spec/checker/http_spec.rb +109 -0
  82. data/spec/checker/memory_spec.rb +64 -0
  83. data/spec/checker/socket_spec.rb +116 -0
  84. data/spec/checker_spec.rb +188 -0
  85. data/spec/child_process/child_process_spec.rb +46 -0
  86. data/spec/client_server_spec.rb +34 -0
  87. data/spec/controller/commands_spec.rb +92 -0
  88. data/spec/controller/controller_spec.rb +133 -0
  89. data/spec/controller/find_objects_spec.rb +150 -0
  90. data/spec/controller/group_spec.rb +110 -0
  91. data/spec/controller/intergration_spec.rb +327 -0
  92. data/spec/controller/load_spec.rb +326 -0
  93. data/spec/controller/races_spec.rb +70 -0
  94. data/spec/controller/stop_on_delete_spec.rb +157 -0
  95. data/spec/dsl/chain_spec.rb +140 -0
  96. data/spec/dsl/checks_spec.rb +202 -0
  97. data/spec/dsl/config_spec.rb +44 -0
  98. data/spec/dsl/dsl_spec.rb +73 -0
  99. data/spec/dsl/getter_spec.rb +223 -0
  100. data/spec/dsl/integration_spec.rb +311 -0
  101. data/spec/dsl/load_spec.rb +52 -0
  102. data/spec/dsl/process_spec.rb +330 -0
  103. data/spec/dsl/sub_procs_spec.rb +93 -0
  104. data/spec/dsl/with_server_spec.rb +104 -0
  105. data/spec/example/em.rb +57 -0
  106. data/spec/example/forking.rb +20 -0
  107. data/spec/example/sample.rb +154 -0
  108. data/spec/fixtures/dsl/0.rb +8 -0
  109. data/spec/fixtures/dsl/0a.rb +8 -0
  110. data/spec/fixtures/dsl/0c.rb +8 -0
  111. data/spec/fixtures/dsl/1.rb +5 -0
  112. data/spec/fixtures/dsl/bad.eye +6 -0
  113. data/spec/fixtures/dsl/configs/1.eye +3 -0
  114. data/spec/fixtures/dsl/configs/2.eye +1 -0
  115. data/spec/fixtures/dsl/configs/3.eye +1 -0
  116. data/spec/fixtures/dsl/configs/4.eye +3 -0
  117. data/spec/fixtures/dsl/empty.eye +20 -0
  118. data/spec/fixtures/dsl/include_test.eye +5 -0
  119. data/spec/fixtures/dsl/include_test/1.rb +6 -0
  120. data/spec/fixtures/dsl/include_test/ha.rb +4 -0
  121. data/spec/fixtures/dsl/include_test2.eye +5 -0
  122. data/spec/fixtures/dsl/integration.eye +30 -0
  123. data/spec/fixtures/dsl/integration2.eye +32 -0
  124. data/spec/fixtures/dsl/integration_locks.eye +30 -0
  125. data/spec/fixtures/dsl/integration_sor.eye +32 -0
  126. data/spec/fixtures/dsl/integration_sor2.eye +27 -0
  127. data/spec/fixtures/dsl/integration_sor3.eye +32 -0
  128. data/spec/fixtures/dsl/load.eye +25 -0
  129. data/spec/fixtures/dsl/load2.eye +7 -0
  130. data/spec/fixtures/dsl/load2_dup2.eye +13 -0
  131. data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
  132. data/spec/fixtures/dsl/load3.eye +10 -0
  133. data/spec/fixtures/dsl/load4.eye +7 -0
  134. data/spec/fixtures/dsl/load5.eye +8 -0
  135. data/spec/fixtures/dsl/load6.eye +17 -0
  136. data/spec/fixtures/dsl/load_dubls.eye +36 -0
  137. data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
  138. data/spec/fixtures/dsl/load_error.eye +5 -0
  139. data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
  140. data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
  141. data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
  142. data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
  143. data/spec/fixtures/dsl/load_int.eye +8 -0
  144. data/spec/fixtures/dsl/load_int2.eye +13 -0
  145. data/spec/fixtures/dsl/load_logger.eye +26 -0
  146. data/spec/fixtures/dsl/load_logger2.eye +3 -0
  147. data/spec/fixtures/dsl/long_load.eye +5 -0
  148. data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
  149. data/spec/fixtures/dsl/subfolder2.eye +9 -0
  150. data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
  151. data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
  152. data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
  153. data/spec/fixtures/dsl/subfolder3.eye +8 -0
  154. data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
  155. data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
  156. data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
  157. data/spec/fixtures/dsl/subfolder4.eye +6 -0
  158. data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
  159. data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
  160. data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
  161. data/spec/mock_spec.rb +32 -0
  162. data/spec/process/checks/child_checks_spec.rb +79 -0
  163. data/spec/process/checks/cpu_spec.rb +114 -0
  164. data/spec/process/checks/ctime_spec.rb +43 -0
  165. data/spec/process/checks/fsize_spec.rb +22 -0
  166. data/spec/process/checks/http_spec.rb +52 -0
  167. data/spec/process/checks/intergration_spec.rb +32 -0
  168. data/spec/process/checks/memory_spec.rb +113 -0
  169. data/spec/process/child_process_spec.rb +125 -0
  170. data/spec/process/config_spec.rb +75 -0
  171. data/spec/process/controller_spec.rb +173 -0
  172. data/spec/process/monitoring_spec.rb +180 -0
  173. data/spec/process/restart_spec.rb +174 -0
  174. data/spec/process/scheduler_spec.rb +150 -0
  175. data/spec/process/start_spec.rb +261 -0
  176. data/spec/process/states_history_spec.rb +118 -0
  177. data/spec/process/stop_spec.rb +150 -0
  178. data/spec/process/system_spec.rb +100 -0
  179. data/spec/process/triggers/flapping_spec.rb +81 -0
  180. data/spec/process/update_config_spec.rb +63 -0
  181. data/spec/spec_helper.rb +120 -0
  182. data/spec/support/rr_celluloid.rb +36 -0
  183. data/spec/support/scheduler_hack.rb +16 -0
  184. data/spec/support/spec_support.rb +164 -0
  185. data/spec/system_resources_spec.rb +59 -0
  186. data/spec/system_spec.rb +170 -0
  187. data/spec/utils/alive_array_spec.rb +50 -0
  188. data/spec/utils/celluloid_chain_spec.rb +82 -0
  189. data/spec/utils/tail_spec.rb +21 -0
  190. 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