god 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|