god 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/History.txt +67 -1
  2. data/Manifest.txt +3 -4
  3. data/Rakefile +1 -1
  4. data/bin/god +19 -1
  5. data/lib/god.rb +86 -49
  6. data/lib/god/cli/command.rb +7 -1
  7. data/lib/god/cli/run.rb +58 -0
  8. data/lib/god/condition.rb +6 -2
  9. data/lib/god/conditions/cpu_usage.rb +7 -6
  10. data/lib/god/conditions/http_response_code.rb +5 -1
  11. data/lib/god/conditions/memory_usage.rb +7 -6
  12. data/lib/god/conditions/process_exits.rb +15 -10
  13. data/lib/god/conditions/process_running.rb +17 -13
  14. data/lib/god/diagnostics.rb +37 -0
  15. data/lib/god/driver.rb +108 -0
  16. data/lib/god/event_handler.rb +41 -1
  17. data/lib/god/logger.rb +69 -19
  18. data/lib/god/metric.rb +2 -2
  19. data/lib/god/process.rb +84 -27
  20. data/lib/god/task.rb +286 -29
  21. data/lib/god/timeline.rb +20 -31
  22. data/lib/god/watch.rb +26 -15
  23. data/test/configs/child_events/child_events.god +0 -5
  24. data/test/configs/child_polls/simple_server.rb +1 -1
  25. data/test/configs/daemon_events/simple_server_stop.rb +2 -0
  26. data/test/configs/stress/stress.god +1 -1
  27. data/test/configs/test.rb +12 -28
  28. data/test/test_condition.rb +8 -0
  29. data/test/test_conditions_http_response_code.rb +5 -5
  30. data/test/test_conditions_process_running.rb +6 -4
  31. data/test/test_driver.rb +11 -0
  32. data/test/test_event_handler.rb +7 -0
  33. data/test/test_god.rb +63 -62
  34. data/test/test_metric.rb +0 -16
  35. data/test/test_process.rb +29 -1
  36. data/test/test_task.rb +177 -1
  37. data/test/test_timeline.rb +2 -1
  38. data/test/test_watch.rb +24 -6
  39. metadata +6 -8
  40. data/lib/god/hub.rb +0 -222
  41. data/lib/god/timer.rb +0 -87
  42. data/test/test_hub.rb +0 -240
  43. data/test/test_timer.rb +0 -69
@@ -1,87 +0,0 @@
1
- module God
2
-
3
- class TimerEvent
4
- attr_accessor :condition, :at
5
-
6
- def initialize(condition, interval)
7
- self.condition = condition
8
- self.at = Time.now.to_i + interval
9
- end
10
- end
11
-
12
- class Timer
13
- INTERVAL = 0.25
14
-
15
- attr_reader :events, :timer
16
-
17
- @@timer = nil
18
-
19
- def self.get
20
- @@timer ||= Timer.new
21
- end
22
-
23
- def self.reset
24
- @@timer = nil
25
- end
26
-
27
- # Start the scheduler loop to handle events
28
- def initialize
29
- @events = []
30
- @mutex = Mutex.new
31
-
32
- @timer = Thread.new do
33
- loop do
34
- begin
35
- # get the current time
36
- t = Time.now.to_i
37
-
38
- # iterate over each event and trigger any that are due
39
- @events.each do |event|
40
- if t >= event.at
41
- self.trigger(event)
42
- @mutex.synchronize do
43
- @events.delete(event)
44
- end
45
- else
46
- break
47
- end
48
- end
49
-
50
- # sleep until next check
51
- sleep INTERVAL
52
- rescue Exception => e
53
- message = format("Unhandled exception (%s): %s\n%s",
54
- e.class, e.message, e.backtrace.join("\n"))
55
- applog(nil, :fatal, message)
56
- sleep INTERVAL
57
- end
58
- end
59
- end
60
- end
61
-
62
- # Create and register a new TimerEvent with the given parameters
63
- def schedule(condition, interval = condition.interval)
64
- @mutex.synchronize do
65
- @events << TimerEvent.new(condition, interval)
66
- @events.sort! { |x, y| x.at <=> y.at }
67
- end
68
- end
69
-
70
- # Remove any TimerEvents for the given condition
71
- def unschedule(condition)
72
- @mutex.synchronize do
73
- @events.reject! { |x| x.condition == condition }
74
- end
75
- end
76
-
77
- def trigger(event)
78
- Hub.trigger(event.condition)
79
- end
80
-
81
- # Join the timer thread
82
- def join
83
- @timer.join
84
- end
85
- end
86
-
87
- end
@@ -1,240 +0,0 @@
1
- require File.dirname(__FILE__) + '/helper'
2
-
3
- class TestHub < Test::Unit::TestCase
4
- def setup
5
- God::Socket.stubs(:new).returns(true)
6
- God.reset
7
-
8
- God.watch do |w|
9
- w.name = 'foo'
10
- w.start = 'bar'
11
- w.interval = 10
12
- end
13
-
14
- @watch = God.watches['foo']
15
- end
16
-
17
- # attach
18
-
19
- def test_attach_should_store_condition_metric_association
20
- c = Conditions::FakePollCondition.new
21
- m = Metric.new(@watch, :foo)
22
- Hub.attach(c, m)
23
-
24
- assert_equal m, Hub.directory[c]
25
- end
26
-
27
- def test_attach_should_schedule_for_poll_condition
28
- c = Conditions::FakePollCondition.new
29
- m = Metric.new(@watch, :foo)
30
-
31
- Timer.any_instance.expects(:schedule).with(c, 0)
32
-
33
- Hub.attach(c, m)
34
- end
35
-
36
- def test_attach_should_regsiter_for_event_condition
37
- c = Conditions::FakeEventCondition.new
38
- m = Metric.new(@watch, :foo)
39
-
40
- c.expects(:register)
41
-
42
- Hub.attach(c, m)
43
- end
44
-
45
- # detach
46
-
47
- def test_detach_should_remove_condition_metric_association
48
- c = Conditions::FakePollCondition.new
49
- m = Metric.new(@watch, :foo)
50
-
51
- Hub.attach(c, m)
52
- Hub.detach(c)
53
-
54
- assert_nil Hub.directory[c]
55
- end
56
-
57
- def test_detach_should_unschedule_poll_conditions
58
- c = Conditions::FakePollCondition.new
59
- m = Metric.new(@watch, :foo)
60
- Hub.attach(c, m)
61
-
62
- Timer.any_instance.expects(:unschedule).with(c)
63
- c.expects(:deregister).never
64
-
65
- Hub.detach(c)
66
- end
67
-
68
- def test_detach_should_deregister_event_conditions
69
- c = Conditions::FakeEventCondition.new
70
- m = Metric.new(@watch, :foo)
71
- Hub.attach(c, m)
72
-
73
- c.expects(:deregister).once
74
-
75
- Hub.detach(c)
76
- end
77
-
78
- # trigger
79
-
80
- def test_trigger_should_handle_poll_for_poll_condition
81
- c = Conditions::FakePollCondition.new
82
- Hub.expects(:handle_poll).with(c)
83
-
84
- Hub.trigger(c)
85
- end
86
-
87
- def test_trigger_should_handle_event_for_event_condition
88
- c = Conditions::FakeEventCondition.new
89
- Hub.expects(:handle_event).with(c)
90
-
91
- Hub.trigger(c)
92
- end
93
-
94
- # handle_poll
95
-
96
- def test_handle_poll_no_change_should_reschedule
97
- c = Conditions::FakePollCondition.new
98
- c.interval = 10
99
-
100
- m = Metric.new(@watch, {true => :up})
101
- Hub.attach(c, m)
102
-
103
- c.expects(:test).returns(false)
104
- Timer.any_instance.expects(:schedule)
105
-
106
- no_stdout do
107
- t = Hub.handle_poll(c)
108
- t.join
109
- end
110
- end
111
-
112
- def test_handle_poll_change_should_move
113
- c = Conditions::FakePollCondition.new
114
- c.interval = 10
115
-
116
- m = Metric.new(@watch, {true => :up})
117
- Hub.attach(c, m)
118
-
119
- c.expects(:test).returns(true)
120
- @watch.expects(:move).with(:up)
121
-
122
- no_stdout do
123
- t = Hub.handle_poll(c)
124
- t.join
125
- end
126
- end
127
-
128
- def test_handle_poll_should_not_abort_on_exception
129
- c = Conditions::FakePollCondition.new
130
- c.interval = 10
131
-
132
- m = Metric.new(@watch, {true => :up})
133
- Hub.attach(c, m)
134
-
135
- c.expects(:test).raises(StandardError.new)
136
-
137
- assert_nothing_raised do
138
- no_stdout do
139
- t = Hub.handle_poll(c)
140
- t.join
141
- end
142
- end
143
- end
144
-
145
- def test_handle_poll_should_use_overridden_transition
146
- c = Conditions::Tries.new
147
- c.times = 1
148
- c.transition = :start
149
- c.prepare
150
-
151
- m = Metric.new(@watch, {true => :up})
152
- Hub.attach(c, m)
153
-
154
- @watch.expects(:move).with(:start)
155
-
156
- no_stdout do
157
- t = Hub.handle_poll(c)
158
- t.join
159
- end
160
- end
161
-
162
- def test_handle_poll_should_notify_if_triggering
163
- c = Conditions::FakePollCondition.new
164
- c.interval = 10
165
- c.notify = 'tom'
166
-
167
- m = Metric.new(@watch, {true => :up})
168
- Hub.attach(c, m)
169
-
170
- c.expects(:test).returns(true)
171
- Hub.expects(:notify)
172
-
173
- no_stdout do
174
- t = Hub.handle_poll(c)
175
- t.join
176
- end
177
- end
178
-
179
- def test_handle_poll_should_not_notify_if_not_triggering
180
- c = Conditions::FakePollCondition.new
181
- c.interval = 10
182
- c.notify = 'tom'
183
-
184
- m = Metric.new(@watch, {true => :up})
185
- Hub.attach(c, m)
186
-
187
- c.expects(:test).returns(false)
188
- Hub.expects(:notify).never
189
-
190
- no_stdout do
191
- t = Hub.handle_poll(c)
192
- t.join
193
- end
194
- end
195
-
196
- # handle_event
197
-
198
- def test_handle_event_should_move
199
- c = Conditions::FakeEventCondition.new
200
-
201
- m = Metric.new(@watch, {true => :up})
202
- Hub.attach(c, m)
203
-
204
- @watch.expects(:move).with(:up)
205
-
206
- no_stdout do
207
- t = Hub.handle_event(c)
208
- t.join
209
- end
210
- end
211
-
212
- def test_handle_event_should_notify_if_triggering
213
- c = Conditions::FakeEventCondition.new
214
- c.notify = 'tom'
215
-
216
- m = Metric.new(@watch, {true => :up})
217
- Hub.attach(c, m)
218
-
219
- Hub.expects(:notify)
220
-
221
- no_stdout do
222
- t = Hub.handle_event(c)
223
- t.join
224
- end
225
- end
226
-
227
- def test_handle_event_should_not_notify_if_no_notify_set
228
- c = Conditions::FakeEventCondition.new
229
-
230
- m = Metric.new(@watch, {true => :up})
231
- Hub.attach(c, m)
232
-
233
- Hub.expects(:notify).never
234
-
235
- no_stdout do
236
- t = Hub.handle_event(c)
237
- t.join
238
- end
239
- end
240
- end
@@ -1,69 +0,0 @@
1
- require File.dirname(__FILE__) + '/helper'
2
-
3
- class TestTimer < Test::Unit::TestCase
4
- def setup
5
- Timer.reset
6
- @t = Timer.get
7
- end
8
-
9
- def test_new_timer_should_have_no_events
10
- assert_equal 0, @t.events.size
11
- end
12
-
13
- def test_schedule_should_queue_event
14
- Time.stubs(:now).returns(0)
15
-
16
- w = Watch.new
17
- @t.schedule(stub(:interval => 20))
18
-
19
- assert_equal 1, @t.events.size
20
- end
21
-
22
- def test_timer_should_remove_expired_events
23
- @t.schedule(stub(:interval => 0))
24
- sleep(0.3)
25
- assert_equal 0, @t.events.size
26
- end
27
-
28
- def test_timer_should_remove_only_expired_events
29
- @t.schedule(stub(:interval => 0))
30
- @t.schedule(stub(:interval => 1000))
31
- sleep(0.3)
32
- assert_equal 1, @t.events.size
33
- end
34
-
35
- def test_timer_should_sort_timer_events
36
- @t.schedule(stub(:interval => 1000))
37
- @t.schedule(stub(:interval => 800))
38
- @t.schedule(stub(:interval => 900))
39
- @t.schedule(stub(:interval => 100))
40
- sleep(0.3)
41
- assert_equal [100, 800, 900, 1000], @t.events.map { |x| x.condition.interval }
42
- end
43
-
44
- def test_unschedule_should_remove_conditions
45
- a = stub()
46
- b = stub()
47
- @t.schedule(a, 100)
48
- @t.schedule(b, 200)
49
- assert_equal 2, @t.events.size
50
- @t.unschedule(a)
51
- assert_equal 1, @t.events.size
52
- end
53
-
54
- def test_time_should_recover_from_exceptions
55
- @t.expects(:trigger).raises(Exception.new)
56
- no_stdout do
57
- @t.schedule(stub(:interval => 0))
58
- sleep(0.3)
59
- @t.schedule(stub(:interval => 0))
60
- end
61
- end
62
-
63
- # join
64
-
65
- def test_join_should_join
66
- Thread.any_instance.expects(:join)
67
- @t.join
68
- end
69
- end