dosire-god 0.7.9
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 +261 -0
- data/Manifest.txt +107 -0
- data/README.txt +59 -0
- data/Rakefile +35 -0
- data/bin/god +127 -0
- data/examples/events.god +84 -0
- data/examples/gravatar.god +54 -0
- data/examples/single.god +66 -0
- data/ext/god/extconf.rb +55 -0
- data/ext/god/kqueue_handler.c +123 -0
- data/ext/god/netlink_handler.c +167 -0
- data/init/god +42 -0
- data/lib/god/behavior.rb +52 -0
- data/lib/god/behaviors/clean_pid_file.rb +21 -0
- data/lib/god/behaviors/clean_unix_socket.rb +21 -0
- data/lib/god/behaviors/notify_when_flapping.rb +51 -0
- data/lib/god/cli/command.rb +206 -0
- data/lib/god/cli/run.rb +177 -0
- data/lib/god/cli/version.rb +23 -0
- data/lib/god/condition.rb +96 -0
- data/lib/god/conditions/always.rb +23 -0
- data/lib/god/conditions/complex.rb +86 -0
- data/lib/god/conditions/cpu_usage.rb +80 -0
- data/lib/god/conditions/degrading_lambda.rb +52 -0
- data/lib/god/conditions/disk_usage.rb +27 -0
- data/lib/god/conditions/flapping.rb +128 -0
- data/lib/god/conditions/http_response_code.rb +168 -0
- data/lib/god/conditions/lambda.rb +25 -0
- data/lib/god/conditions/memory_usage.rb +82 -0
- data/lib/god/conditions/process_exits.rb +72 -0
- data/lib/god/conditions/process_running.rb +74 -0
- data/lib/god/conditions/tries.rb +44 -0
- data/lib/god/configurable.rb +57 -0
- data/lib/god/contact.rb +106 -0
- data/lib/god/contacts/email.rb +95 -0
- data/lib/god/dependency_graph.rb +41 -0
- data/lib/god/diagnostics.rb +37 -0
- data/lib/god/driver.rb +206 -0
- data/lib/god/errors.rb +24 -0
- data/lib/god/event_handler.rb +111 -0
- data/lib/god/event_handlers/dummy_handler.rb +13 -0
- data/lib/god/event_handlers/kqueue_handler.rb +17 -0
- data/lib/god/event_handlers/netlink_handler.rb +13 -0
- data/lib/god/logger.rb +120 -0
- data/lib/god/metric.rb +59 -0
- data/lib/god/process.rb +327 -0
- data/lib/god/registry.rb +32 -0
- data/lib/god/simple_logger.rb +53 -0
- data/lib/god/socket.rb +96 -0
- data/lib/god/sugar.rb +47 -0
- data/lib/god/system/portable_poller.rb +42 -0
- data/lib/god/system/process.rb +42 -0
- data/lib/god/system/slash_proc_poller.rb +82 -0
- data/lib/god/task.rb +487 -0
- data/lib/god/timeline.rb +25 -0
- data/lib/god/trigger.rb +43 -0
- data/lib/god/watch.rb +183 -0
- data/lib/god.rb +644 -0
- data/test/configs/child_events/child_events.god +44 -0
- data/test/configs/child_events/simple_server.rb +3 -0
- data/test/configs/child_polls/child_polls.god +37 -0
- data/test/configs/child_polls/simple_server.rb +12 -0
- data/test/configs/complex/complex.god +59 -0
- data/test/configs/complex/simple_server.rb +3 -0
- data/test/configs/contact/contact.god +74 -0
- data/test/configs/contact/simple_server.rb +3 -0
- data/test/configs/daemon_events/daemon_events.god +37 -0
- data/test/configs/daemon_events/simple_server.rb +8 -0
- data/test/configs/daemon_events/simple_server_stop.rb +11 -0
- data/test/configs/daemon_polls/daemon_polls.god +17 -0
- data/test/configs/daemon_polls/simple_server.rb +6 -0
- data/test/configs/degrading_lambda/degrading_lambda.god +31 -0
- data/test/configs/degrading_lambda/tcp_server.rb +15 -0
- data/test/configs/matias/matias.god +50 -0
- data/test/configs/real.rb +59 -0
- data/test/configs/running_load/running_load.god +16 -0
- data/test/configs/stress/simple_server.rb +3 -0
- data/test/configs/stress/stress.god +15 -0
- data/test/configs/task/logs/.placeholder +0 -0
- data/test/configs/task/task.god +26 -0
- data/test/configs/test.rb +61 -0
- data/test/helper.rb +151 -0
- data/test/suite.rb +6 -0
- data/test/test_behavior.rb +21 -0
- data/test/test_condition.rb +50 -0
- data/test/test_conditions_disk_usage.rb +56 -0
- data/test/test_conditions_http_response_code.rb +109 -0
- data/test/test_conditions_process_running.rb +44 -0
- data/test/test_conditions_tries.rb +67 -0
- data/test/test_contact.rb +109 -0
- data/test/test_dependency_graph.rb +62 -0
- data/test/test_driver.rb +11 -0
- data/test/test_event_handler.rb +80 -0
- data/test/test_god.rb +598 -0
- data/test/test_handlers_kqueue_handler.rb +16 -0
- data/test/test_logger.rb +63 -0
- data/test/test_metric.rb +72 -0
- data/test/test_process.rb +246 -0
- data/test/test_registry.rb +15 -0
- data/test/test_socket.rb +42 -0
- data/test/test_sugar.rb +42 -0
- data/test/test_system_portable_poller.rb +17 -0
- data/test/test_system_process.rb +30 -0
- data/test/test_task.rb +262 -0
- data/test/test_timeline.rb +37 -0
- data/test/test_trigger.rb +59 -0
- data/test/test_watch.rb +279 -0
- metadata +186 -0
data/lib/god/timeline.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module God
|
2
|
+
|
3
|
+
class Timeline < Array
|
4
|
+
# Instantiate a new Timeline
|
5
|
+
# +max_size+ is the maximum size to which the timeline should grow
|
6
|
+
#
|
7
|
+
# Returns Timeline
|
8
|
+
def initialize(max_size)
|
9
|
+
super()
|
10
|
+
@max_size = max_size
|
11
|
+
end
|
12
|
+
|
13
|
+
# Push a value onto the Timeline
|
14
|
+
# +val+ is the value to push
|
15
|
+
#
|
16
|
+
# Returns Timeline
|
17
|
+
def push(val)
|
18
|
+
self.concat([val])
|
19
|
+
shift if size > @max_size
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :<<, :push
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/god/trigger.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module God
|
2
|
+
|
3
|
+
class Trigger
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :triggers # {task.name => condition}
|
7
|
+
end
|
8
|
+
|
9
|
+
# init
|
10
|
+
self.triggers = {}
|
11
|
+
@mutex = Mutex.new
|
12
|
+
|
13
|
+
def self.register(condition)
|
14
|
+
@mutex.synchronize do
|
15
|
+
self.triggers[condition.watch.name] ||= []
|
16
|
+
self.triggers[condition.watch.name] << condition
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.deregister(condition)
|
21
|
+
@mutex.synchronize do
|
22
|
+
self.triggers[condition.watch.name].delete(condition)
|
23
|
+
self.triggers.delete(condition.watch.name) if self.triggers[condition.watch.name].empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.broadcast(task, message, payload)
|
28
|
+
return unless self.triggers[task.name]
|
29
|
+
|
30
|
+
@mutex.synchronize do
|
31
|
+
self.triggers[task.name].each do |t|
|
32
|
+
t.process(message, payload)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.reset
|
38
|
+
self.triggers.clear
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/god/watch.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'etc'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module God
|
5
|
+
|
6
|
+
class Watch < Task
|
7
|
+
VALID_STATES = [:init, :up, :start, :restart]
|
8
|
+
INITIAL_STATE = :init
|
9
|
+
|
10
|
+
# config
|
11
|
+
attr_accessor :grace, :start_grace, :stop_grace, :restart_grace
|
12
|
+
|
13
|
+
extend Forwardable
|
14
|
+
def_delegators :@process, :name, :uid, :gid, :start, :stop, :restart,
|
15
|
+
:name=, :uid=, :gid=, :start=, :stop=, :restart=,
|
16
|
+
:pid_file, :pid_file=, :log, :log=, :alive?, :pid,
|
17
|
+
:unix_socket, :unix_socket=, :chroot, :chroot=, :env, :env=
|
18
|
+
#
|
19
|
+
def initialize
|
20
|
+
super
|
21
|
+
|
22
|
+
@process = God::Process.new
|
23
|
+
|
24
|
+
# valid states
|
25
|
+
self.valid_states = VALID_STATES
|
26
|
+
self.initial_state = INITIAL_STATE
|
27
|
+
|
28
|
+
# no grace period by default
|
29
|
+
self.grace = self.start_grace = self.stop_grace = self.restart_grace = 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?
|
33
|
+
super && @process.valid?
|
34
|
+
end
|
35
|
+
|
36
|
+
###########################################################################
|
37
|
+
#
|
38
|
+
# Behavior
|
39
|
+
#
|
40
|
+
###########################################################################
|
41
|
+
|
42
|
+
def behavior(kind)
|
43
|
+
# create the behavior
|
44
|
+
begin
|
45
|
+
b = Behavior.generate(kind, self)
|
46
|
+
rescue NoSuchBehaviorError => e
|
47
|
+
abort e.message
|
48
|
+
end
|
49
|
+
|
50
|
+
# send to block so config can set attributes
|
51
|
+
yield(b) if block_given?
|
52
|
+
|
53
|
+
# abort if the Behavior is invalid, the Behavior will have printed
|
54
|
+
# out its own error messages by now
|
55
|
+
abort unless b.valid?
|
56
|
+
|
57
|
+
self.behaviors << b
|
58
|
+
end
|
59
|
+
|
60
|
+
###########################################################################
|
61
|
+
#
|
62
|
+
# Simple mode
|
63
|
+
#
|
64
|
+
###########################################################################
|
65
|
+
|
66
|
+
def start_if
|
67
|
+
self.transition(:up, :start) do |on|
|
68
|
+
yield(on)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def restart_if
|
73
|
+
self.transition(:up, :restart) do |on|
|
74
|
+
yield(on)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def stop_if
|
79
|
+
self.transition(:up, :stop) do |on|
|
80
|
+
yield(on)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
###########################################################################
|
85
|
+
#
|
86
|
+
# Lifecycle
|
87
|
+
#
|
88
|
+
###########################################################################
|
89
|
+
|
90
|
+
# Enable monitoring
|
91
|
+
def monitor
|
92
|
+
# start monitoring at the first available of the init or up states
|
93
|
+
if !self.metrics[:init].empty?
|
94
|
+
self.move(:init)
|
95
|
+
else
|
96
|
+
self.move(:up)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
###########################################################################
|
101
|
+
#
|
102
|
+
# Actions
|
103
|
+
#
|
104
|
+
###########################################################################
|
105
|
+
|
106
|
+
def action(a, c = nil)
|
107
|
+
if Thread.current != self.driver.thread
|
108
|
+
# called from outside Driver
|
109
|
+
|
110
|
+
# send an async message to Driver
|
111
|
+
self.driver.message(:action, [a, c])
|
112
|
+
else
|
113
|
+
# called from within Driver
|
114
|
+
|
115
|
+
case a
|
116
|
+
when :start
|
117
|
+
call_action(c, :start)
|
118
|
+
sleep(self.start_grace + self.grace)
|
119
|
+
when :restart
|
120
|
+
if self.restart
|
121
|
+
call_action(c, :restart)
|
122
|
+
else
|
123
|
+
action(:stop, c)
|
124
|
+
action(:start, c)
|
125
|
+
end
|
126
|
+
sleep(self.restart_grace + self.grace)
|
127
|
+
when :stop
|
128
|
+
call_action(c, :stop)
|
129
|
+
sleep(self.stop_grace + self.grace)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
def call_action(condition, action)
|
137
|
+
# before
|
138
|
+
before_items = self.behaviors
|
139
|
+
before_items += [condition] if condition
|
140
|
+
before_items.each do |b|
|
141
|
+
info = b.send("before_#{action}")
|
142
|
+
if info
|
143
|
+
msg = "#{self.name} before_#{action}: #{info} (#{b.base_name})"
|
144
|
+
applog(self, :info, msg)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# log
|
149
|
+
if self.send(action)
|
150
|
+
msg = "#{self.name} #{action}: #{self.send(action).to_s}"
|
151
|
+
applog(self, :info, msg)
|
152
|
+
end
|
153
|
+
|
154
|
+
@process.call_action(action)
|
155
|
+
|
156
|
+
# after
|
157
|
+
after_items = self.behaviors
|
158
|
+
after_items += [condition] if condition
|
159
|
+
after_items.each do |b|
|
160
|
+
info = b.send("after_#{action}")
|
161
|
+
if info
|
162
|
+
msg = "#{self.name} after_#{action}: #{info} (#{b.base_name})"
|
163
|
+
applog(self, :info, msg)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
###########################################################################
|
169
|
+
#
|
170
|
+
# Registration
|
171
|
+
#
|
172
|
+
###########################################################################
|
173
|
+
|
174
|
+
def register!
|
175
|
+
God.registry.add(@process)
|
176
|
+
end
|
177
|
+
|
178
|
+
def unregister!
|
179
|
+
God.registry.remove(@process)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|