god 0.6.0 → 0.7.0
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/History.txt +67 -1
- data/Manifest.txt +3 -4
- data/Rakefile +1 -1
- data/bin/god +19 -1
- data/lib/god.rb +86 -49
- data/lib/god/cli/command.rb +7 -1
- data/lib/god/cli/run.rb +58 -0
- data/lib/god/condition.rb +6 -2
- data/lib/god/conditions/cpu_usage.rb +7 -6
- data/lib/god/conditions/http_response_code.rb +5 -1
- data/lib/god/conditions/memory_usage.rb +7 -6
- data/lib/god/conditions/process_exits.rb +15 -10
- data/lib/god/conditions/process_running.rb +17 -13
- data/lib/god/diagnostics.rb +37 -0
- data/lib/god/driver.rb +108 -0
- data/lib/god/event_handler.rb +41 -1
- data/lib/god/logger.rb +69 -19
- data/lib/god/metric.rb +2 -2
- data/lib/god/process.rb +84 -27
- data/lib/god/task.rb +286 -29
- data/lib/god/timeline.rb +20 -31
- data/lib/god/watch.rb +26 -15
- data/test/configs/child_events/child_events.god +0 -5
- data/test/configs/child_polls/simple_server.rb +1 -1
- data/test/configs/daemon_events/simple_server_stop.rb +2 -0
- data/test/configs/stress/stress.god +1 -1
- data/test/configs/test.rb +12 -28
- data/test/test_condition.rb +8 -0
- data/test/test_conditions_http_response_code.rb +5 -5
- data/test/test_conditions_process_running.rb +6 -4
- data/test/test_driver.rb +11 -0
- data/test/test_event_handler.rb +7 -0
- data/test/test_god.rb +63 -62
- data/test/test_metric.rb +0 -16
- data/test/test_process.rb +29 -1
- data/test/test_task.rb +177 -1
- data/test/test_timeline.rb +2 -1
- data/test/test_watch.rb +24 -6
- metadata +6 -8
- data/lib/god/hub.rb +0 -222
- data/lib/god/timer.rb +0 -87
- data/test/test_hub.rb +0 -240
- data/test/test_timer.rb +0 -69
data/lib/god/timer.rb
DELETED
@@ -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
|
data/test/test_hub.rb
DELETED
@@ -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
|
data/test/test_timer.rb
DELETED
@@ -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
|