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