angael 0.0.9 → 0.1.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/lib/angael/manager.rb +23 -26
- data/lib/angael/version.rb +1 -1
- data/lib/angael/worker.rb +27 -15
- metadata +1 -1
data/lib/angael/manager.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'angael/process_helper'
|
2
|
+
require 'logger'
|
2
3
|
module Angael
|
3
4
|
# A Manager has a number of of worker objects. Starting the Manager simply
|
4
5
|
# calls #start! on each worker, then it goes into an infinite loop, waiting
|
@@ -21,13 +22,6 @@ module Angael
|
|
21
22
|
# @opts [Hash] Additional options:
|
22
23
|
# :logger => A logger object, which should follow the Logger class in the
|
23
24
|
# standard library. Default nil, as in no logging.
|
24
|
-
# :log_level => The log level, as defined by the Logger class in the
|
25
|
-
# standard library. One of:
|
26
|
-
# Logger::FATAL
|
27
|
-
# Logger::ERROR
|
28
|
-
# Logger::WARN
|
29
|
-
# Logger::INFO # Default
|
30
|
-
# Logger::DEBUG
|
31
25
|
# :restart_after => If set, 1 worker will be restarted after this number
|
32
26
|
# of seconds. If it is nil (the default), then workers will not get
|
33
27
|
# restarted for no reason. If your workers leak memory, this can help
|
@@ -39,12 +33,6 @@ module Angael
|
|
39
33
|
# TODO: Add a spec for this
|
40
34
|
raise ArgumentError, ':restart_after must be either an Integer greater than zero or nil' if @restart_after && (@restart_after.to_i != @restart_after || @restart_after == 0)
|
41
35
|
@logger = opts[:logger]
|
42
|
-
if @logger
|
43
|
-
@log_level = opts[:log_level] || begin
|
44
|
-
require 'logger' # Only require it if it is absolutely neccessary.
|
45
|
-
Logger::INFO
|
46
|
-
end
|
47
|
-
end
|
48
36
|
end
|
49
37
|
|
50
38
|
|
@@ -54,15 +42,15 @@ module Angael
|
|
54
42
|
workers.each { |w| w.start! }
|
55
43
|
|
56
44
|
trap("CHLD") do
|
57
|
-
|
45
|
+
debug("SIGCHLD Received")
|
58
46
|
@sigchld = true
|
59
47
|
end
|
60
48
|
trap("INT") do
|
61
|
-
|
49
|
+
info("SIGINT Received")
|
62
50
|
@interrupted = true
|
63
51
|
end
|
64
52
|
trap("TERM") do
|
65
|
-
|
53
|
+
info("SIGTERM Received")
|
66
54
|
@interrupted = true
|
67
55
|
end
|
68
56
|
|
@@ -89,24 +77,33 @@ module Angael
|
|
89
77
|
#########
|
90
78
|
|
91
79
|
def stop!
|
92
|
-
|
80
|
+
info("Attempting to gracefully stopping worker manager")
|
93
81
|
# Tell each worker to stop, without waiting to see if it worked.
|
94
82
|
workers.each { |w|
|
95
|
-
|
83
|
+
debug("Calling #stop_without_wait for worker #{w.inspect}")
|
96
84
|
w.stop_without_wait
|
97
|
-
|
85
|
+
debug("Finished call to #stop_without_wait for worker #{w.inspect}")
|
98
86
|
}
|
99
87
|
# Wait for each worker to stop, one at a time.
|
100
88
|
workers.each { |w|
|
101
|
-
|
89
|
+
debug("Calling #stop_with_wait for worker #{w.inspect}")
|
102
90
|
w.stop_with_wait
|
103
|
-
|
91
|
+
debug("Finished call to #stop_with_wait for worker #{w.inspect}")
|
104
92
|
}
|
93
|
+
info("Exiting")
|
105
94
|
exit 0
|
106
95
|
end
|
107
96
|
|
108
|
-
def log(msg)
|
109
|
-
@logger.add(
|
97
|
+
def log(level, msg)
|
98
|
+
@logger.add(level, "#{Time.now.utc} - #{self.class} (pid #{$$}): #{msg}") if @logger
|
99
|
+
end
|
100
|
+
|
101
|
+
def debug(msg)
|
102
|
+
log(Logger::DEBUG, msg)
|
103
|
+
end
|
104
|
+
|
105
|
+
def info(msg)
|
106
|
+
log(Logger::INFO, msg)
|
110
107
|
end
|
111
108
|
|
112
109
|
|
@@ -147,11 +144,11 @@ module Angael
|
|
147
144
|
@seconds_until_restart_next_worker -= LOOP_SLEEP_SECONDS
|
148
145
|
else
|
149
146
|
w = next_worker_to_restart
|
150
|
-
|
147
|
+
debug("Time to restart a worker: Calling #stop_with_wait for worker #{w.inspect}")
|
151
148
|
w.stop_with_wait
|
152
|
-
|
149
|
+
debug("Worker has been stopped: #{w.inspect}")
|
153
150
|
w.start!
|
154
|
-
|
151
|
+
debug("Worker has been restarted: #{w.inspect}")
|
155
152
|
w = nil
|
156
153
|
|
157
154
|
# Reset the counter
|
data/lib/angael/version.rb
CHANGED
data/lib/angael/worker.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'angael/process_helper'
|
2
|
+
require 'logger'
|
2
3
|
module Angael
|
3
4
|
# Usage
|
4
5
|
# include Angael::Worker
|
@@ -28,27 +29,27 @@ module Angael
|
|
28
29
|
@stopping = false
|
29
30
|
|
30
31
|
@pid = fork_child do
|
31
|
-
|
32
|
+
__info("Started")
|
32
33
|
|
33
34
|
if respond_to?(:after_fork)
|
34
|
-
|
35
|
+
__debug("Running after fork callback")
|
35
36
|
after_fork
|
36
|
-
|
37
|
+
__debug("Finished running after fork callback")
|
37
38
|
end
|
38
39
|
|
39
40
|
@interrupted = false
|
40
41
|
trap("INT") do
|
41
|
-
|
42
|
+
__info("SIGINT Received")
|
42
43
|
@interrupted = true
|
43
44
|
end
|
44
45
|
trap("TERM") do
|
45
|
-
|
46
|
+
__info("SIGTERM Received")
|
46
47
|
@interrupted = true
|
47
48
|
end
|
48
49
|
|
49
50
|
loop do
|
50
51
|
if @interrupted
|
51
|
-
|
52
|
+
__info("Child process exiting gracefully")
|
52
53
|
exit 0
|
53
54
|
end
|
54
55
|
work
|
@@ -71,7 +72,7 @@ module Angael
|
|
71
72
|
# Sets stopping? to false.
|
72
73
|
def stop_without_wait
|
73
74
|
unless started?
|
74
|
-
|
75
|
+
__warn("Tried to stop worker with PID #{pid} but it is not started")
|
75
76
|
return false
|
76
77
|
end
|
77
78
|
|
@@ -79,7 +80,7 @@ module Angael
|
|
79
80
|
# stopped the child process.
|
80
81
|
@stopping = true
|
81
82
|
|
82
|
-
|
83
|
+
__debug("Sending SIGINT to child process with pid #{pid}.")
|
83
84
|
send_signal('INT', pid)
|
84
85
|
true
|
85
86
|
end
|
@@ -89,19 +90,19 @@ module Angael
|
|
89
90
|
def stop_with_wait
|
90
91
|
return false unless stop_without_wait
|
91
92
|
|
92
|
-
|
93
|
+
__debug("Waiting for child process with pid #{pid} to stop.")
|
93
94
|
|
94
95
|
counter = 0
|
95
96
|
|
96
97
|
while pid_running? && counter < timeout
|
97
98
|
sleep 1
|
98
99
|
counter += 1
|
99
|
-
|
100
|
+
__info("Sending SIGINT to child process with pid #{pid}. Attempt Count: #{counter}.")
|
100
101
|
send_signal('INT', pid)
|
101
102
|
end
|
102
103
|
|
103
104
|
if pid_running?
|
104
|
-
|
105
|
+
__warn("Child process with pid #{pid} did not stop within #{timeout} seconds of SIGINT. Sending SIGKILL to child process.")
|
105
106
|
send_signal('KILL', pid)
|
106
107
|
sleep 1
|
107
108
|
end
|
@@ -109,7 +110,7 @@ module Angael
|
|
109
110
|
if pid_running?
|
110
111
|
# SIGKILL didn't work.
|
111
112
|
msg = "Unable to kill child process with PID: #{pid}"
|
112
|
-
|
113
|
+
__error(msg)
|
113
114
|
raise ChildProcessNotStoppedError, msg
|
114
115
|
end
|
115
116
|
end
|
@@ -136,10 +137,21 @@ module Angael
|
|
136
137
|
end
|
137
138
|
|
138
139
|
|
139
|
-
def __log(msg)
|
140
|
-
log(msg) if respond_to?(:log)
|
140
|
+
def __log(level, msg)
|
141
|
+
log(level, msg) if respond_to?(:log)
|
142
|
+
end
|
143
|
+
def __debug(msg)
|
144
|
+
__log(Logger::DEBUG, msg)
|
145
|
+
end
|
146
|
+
def __info(msg)
|
147
|
+
__log(Logger::INFO, msg)
|
148
|
+
end
|
149
|
+
def __warn(msg)
|
150
|
+
__log(Logger::WARN, msg)
|
151
|
+
end
|
152
|
+
def __error(msg)
|
153
|
+
__log(Logger::ERROR, msg)
|
141
154
|
end
|
142
|
-
|
143
155
|
|
144
156
|
# In seconds
|
145
157
|
def timeout
|