webapp_worker 0.0.2 → 0.0.3
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/README.markdown +38 -24
- data/bin/waw +4 -5
- data/lib/webapp_worker.rb +1 -0
- data/lib/webapp_worker/application.rb +51 -162
- data/lib/webapp_worker/system.rb +205 -0
- data/lib/webapp_worker/version.rb +1 -1
- metadata +7 -6
data/README.markdown
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## Information
|
2
2
|
|
3
|
-
Provides a way to have workers on your webapp servers,
|
3
|
+
Provides a way to have workers on your webapp servers, especially useful for webapps that tend to scale up and down with X amount of servers in the load balancer. Also good way to not use another dependent resource like a job scheduler/queue. Keeps your application all packaged up nicely, no cron jobs to set, nothing else to think about setting up and nothing else to maintain.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -14,8 +14,10 @@ or use it in your Gemfile
|
|
14
14
|
|
15
15
|
waw -e development -f jobs.yml (parses data)
|
16
16
|
waw -e development -f jobs.yml -j (parses and shows jobs)
|
17
|
-
waw -e development -f jobs.yml -n
|
17
|
+
waw -e development -f jobs.yml -n 4 (parses and shows the next N run times, by job)
|
18
18
|
waw -e development -f jobs.yml -r (parses and starts to run)
|
19
|
+
waw -e development -f jobs.yml -d (parses and turns on debugging)
|
20
|
+
waw -e development -f jobs.yml -v (parses and turns on verbose logging)
|
19
21
|
|
20
22
|
## Using in your webapp
|
21
23
|
|
@@ -45,39 +47,51 @@ You don't have to use a jobs file, you can specify the yaml or hash in the code
|
|
45
47
|
|
46
48
|
## Example Output of waw
|
47
49
|
|
50
|
+
See if Webapp Worker can parse the jobs file and show you all the jobs it can run from the file
|
51
|
+
|
48
52
|
$ waw -e local -f config/jobs.yml -j
|
49
53
|
Job File: config/jobs.yml
|
50
54
|
|
51
55
|
Host: localhost
|
52
56
|
Mailto:
|
53
57
|
Environment: development
|
54
|
-
Amount of Jobs:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
58
|
+
Amount of Jobs: 3
|
59
|
+
|
60
|
+
Job: rake job:run
|
61
|
+
Job: rake job:run
|
62
|
+
Job: rake job:run
|
63
|
+
|
64
|
+
See when the jobs are supposed to run next, next two times, next three times, etc...
|
65
|
+
|
66
|
+
$ waw -e local -f config/jobs.yml -n 4
|
67
|
+
Job: rake job:run
|
68
|
+
Next Run Time(s): [2012-01-03 22:00:00 -0700, 2012-01-03 22:05:00 -0700, 2012-01-03 22:10:00 -0700, 2012-01-03 22:15:00 -0700]
|
69
|
+
Job: rake job:run
|
70
|
+
Next Run Time(s): [2012-01-03 22:00:00 -0700, 2012-01-03 22:05:00 -0700, 2012-01-03 22:10:00 -0700, 2012-01-03 22:15:00 -0700]
|
71
|
+
Job: rake job:run
|
72
|
+
|
73
|
+
$ waw -e local -f config/jobs.yml -r (optional -d and -v for debug and verbose)
|
74
|
+
Running Jobs
|
75
|
+
|
76
|
+
## Other Options
|
77
|
+
|
78
|
+
You may want to know what version of the gem Webapp Worker is using, so just send a USR1 signal to it
|
79
|
+
|
80
|
+
$ kill -s USR1 11682
|
81
|
+
Webapp Worker Version: 0.0.3
|
82
|
+
|
83
|
+
You may need to turn on debugging for the Webapp Worker while its running, so just send a USR2 signal to it
|
84
|
+
|
85
|
+
$ kill -s USR2 11682
|
86
|
+
Changed logger level to Debug
|
74
87
|
|
75
88
|
## Roadmap
|
76
89
|
|
77
|
-
-
|
90
|
+
- Use the mailto attribute in application to actually do something
|
78
91
|
- Start having the webapp worker registering to a central point or do UDP mutlicasting to find each other.
|
79
92
|
- Once self registering is enabled, webapp_workers need to communicate effectively.
|
80
|
-
- Once communication is
|
93
|
+
- Once communication is established webapp_workers need to do the scheduling for themselves.
|
94
|
+
- Do logging for each type of job in a jobs directory under tmp/webapp_worker, allowing for troubleshooting.
|
81
95
|
- Spit out reports of the different jobs and how fast they run.
|
82
96
|
|
83
97
|
## Contributing
|
data/bin/waw
CHANGED
@@ -15,7 +15,7 @@ where [options] are:
|
|
15
15
|
opt :jobfile, "A YAML config file", :type => String, :short => "-f"
|
16
16
|
opt :run, "Run the jobs", :default => false, :short => "-r"
|
17
17
|
opt :jobs, "Show the jobs", :default => false, :short => "-j"
|
18
|
-
opt :nextrun, "Find the next
|
18
|
+
opt :nextrun, "Find the next N run times, by job (use an integer)", :type => Integer, :short => "-n"
|
19
19
|
opt :debug, "Local Debug", :short => "-d"
|
20
20
|
opt :verbose, "Verbose Output", :short => "-v"
|
21
21
|
end
|
@@ -30,8 +30,8 @@ a.parse_yaml(job_file)
|
|
30
30
|
|
31
31
|
if opts[:nextrun] != nil
|
32
32
|
a.next_command_run?(opts[:nextrun]).each do |command,time|
|
33
|
-
puts "
|
34
|
-
puts " Next Run: #{time}"
|
33
|
+
puts "Job: #{command}"
|
34
|
+
puts " Next Run Time(s): #{time}"
|
35
35
|
end
|
36
36
|
elsif opts[:run] == false && opts[:jobs] == false
|
37
37
|
puts
|
@@ -49,8 +49,7 @@ elsif opts[:run] == false && opts[:jobs] == true
|
|
49
49
|
puts
|
50
50
|
a.jobs.each do |job|
|
51
51
|
j = WebappWorker::Job.new(job)
|
52
|
-
puts "
|
53
|
-
puts " Next Run: #{j.next_run?}"
|
52
|
+
puts "Job: #{j.command}"
|
54
53
|
end
|
55
54
|
else
|
56
55
|
puts "Running Jobs"
|
data/lib/webapp_worker.rb
CHANGED
@@ -1,20 +1,6 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'timeout'
|
3
3
|
require 'open4'
|
4
|
-
require 'logger'
|
5
|
-
|
6
|
-
module Process
|
7
|
-
class << self
|
8
|
-
def alive?(pid)
|
9
|
-
begin
|
10
|
-
Process.kill(0, pid.to_i)
|
11
|
-
true
|
12
|
-
rescue Errno::ESRCH
|
13
|
-
false
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
4
|
|
19
5
|
module WebappWorker
|
20
6
|
class Application
|
@@ -44,6 +30,44 @@ module WebappWorker
|
|
44
30
|
return Socket.gethostname.downcase
|
45
31
|
end
|
46
32
|
|
33
|
+
def check_file_modification_time
|
34
|
+
mtime = File.mtime(@file)
|
35
|
+
|
36
|
+
if mtime != @file_mtime
|
37
|
+
@file_mtime = mtime
|
38
|
+
self.parse_yaml(@file)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def next_command_run?(til)
|
43
|
+
commands = {}
|
44
|
+
c = {}
|
45
|
+
next_commands = {}
|
46
|
+
new_jobs = []
|
47
|
+
|
48
|
+
(0..til).each do |i|
|
49
|
+
@jobs.each do |j|
|
50
|
+
new_jobs << j
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
new_jobs.flatten.each do |job|
|
55
|
+
j = WebappWorker::Job.new(job)
|
56
|
+
commands.store(j.command,j.next_runs?(til))
|
57
|
+
end
|
58
|
+
|
59
|
+
(commands.sort_by { |key,value| value }).collect { |key,value| c.store(key,value) }
|
60
|
+
|
61
|
+
counter = 0
|
62
|
+
c.each do |key,value|
|
63
|
+
next_commands.store(key,value)
|
64
|
+
counter = counter + 1
|
65
|
+
break if counter >= @jobs.length
|
66
|
+
end
|
67
|
+
|
68
|
+
return next_commands
|
69
|
+
end
|
70
|
+
|
47
71
|
def next_command_run_time?
|
48
72
|
commands = {}
|
49
73
|
c = {}
|
@@ -79,162 +103,26 @@ module WebappWorker
|
|
79
103
|
return next_commands
|
80
104
|
end
|
81
105
|
|
82
|
-
def check_file_modification_time
|
83
|
-
mtime = File.mtime(@file)
|
84
|
-
|
85
|
-
if mtime != @file_mtime
|
86
|
-
@file_mtime = mtime
|
87
|
-
self.parse_yaml(@file)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def check_for_directory
|
92
|
-
dir = "/tmp/webapp_worker"
|
93
|
-
|
94
|
-
if Dir.exists?(dir)
|
95
|
-
else
|
96
|
-
Dir.mkdir(dir, 0700)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def create_pid(logger)
|
101
|
-
logger.info "Creating Pid File at /tmp/webapp_worker/waw.pid"
|
102
|
-
|
103
|
-
File.open("/tmp/webapp_worker/waw.pid", 'w') { |f| f.write(Process.pid) }
|
104
|
-
$0="Web App Worker - Job File: #{@file}"
|
105
|
-
|
106
|
-
logger.info "Pid File created: #{Process.pid} at /tmp/webapp_worker/waw.pid"
|
107
|
-
end
|
108
|
-
|
109
|
-
def check_for_process(logger)
|
110
|
-
file = "/tmp/webapp_worker/waw.pid"
|
111
|
-
|
112
|
-
if File.exists?(file)
|
113
|
-
possible_pid = ""
|
114
|
-
pid_file = File.open(file, 'r').each { |f| possible_pid+= f }
|
115
|
-
pid_file.close
|
116
|
-
|
117
|
-
if Process.alive?(possible_pid)
|
118
|
-
puts "Already found webapp_worker running, pid is: #{possible_pid}, exiting..."
|
119
|
-
logger.fatal "Found webapp_worker already running with pid: #{possible_pid}, Pid File: #{file} exiting..."
|
120
|
-
exit 1
|
121
|
-
else
|
122
|
-
logger.warn "Found pid file, but no process running, recreating pid file with my pid: #{Process.pid}"
|
123
|
-
File.delete(file)
|
124
|
-
self.create_pid(logger)
|
125
|
-
end
|
126
|
-
else
|
127
|
-
self.create_pid(logger)
|
128
|
-
end
|
129
|
-
|
130
|
-
logger.info "Starting Webapp Worker"
|
131
|
-
end
|
132
|
-
|
133
|
-
def graceful_termination(logger)
|
134
|
-
stop_loop = true
|
135
|
-
|
136
|
-
begin
|
137
|
-
puts
|
138
|
-
puts "Graceful Termination started, waiting 60 seconds before KILL signal send"
|
139
|
-
logger.info "Graceful Termination started, waiting 60 seconds before KILL signal send"
|
140
|
-
|
141
|
-
Timeout::timeout(60) do
|
142
|
-
@command_processes.each do |pid,command|
|
143
|
-
logger.debug "Sending INT Signal to #{command} Process with PID: #{pid}"
|
144
|
-
begin
|
145
|
-
Process.kill("INT",pid.to_i)
|
146
|
-
rescue => error
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
@threads.each do |thread,command|
|
151
|
-
thread.join
|
152
|
-
end
|
153
|
-
end
|
154
|
-
rescue Timeout::Error
|
155
|
-
puts "Graceful Termination bypassed, killing processes and threads"
|
156
|
-
logger.info "Graceful Termination bypassed, killing processes and threads"
|
157
|
-
|
158
|
-
@command_processes.each do |pid,command|
|
159
|
-
logger.debug "Killing #{command} Process with PID: #{pid}"
|
160
|
-
begin
|
161
|
-
Process.kill("KILL",pid.to_i)
|
162
|
-
rescue => error
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
@threads.each do |thread,command|
|
167
|
-
logger.debug "Killing Command Thread: #{command}"
|
168
|
-
Thread.kill(thread)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
puts "Stopping Webapp Worker"
|
173
|
-
logger.info "Stopping Webapp Worker"
|
174
|
-
file = "/tmp/webapp_worker/waw.pid"
|
175
|
-
File.delete(file)
|
176
|
-
exit 0
|
177
|
-
end
|
178
|
-
|
179
106
|
def run(debug=nil,verbose=nil)
|
180
|
-
self.check_for_directory
|
181
|
-
|
182
|
-
logger = Logger.new("/tmp/webapp_worker/#{@environment}.log", 5, 5242880)
|
183
|
-
|
184
|
-
if debug
|
185
|
-
logger.level = Logger::DEBUG
|
186
|
-
elsif verbose
|
187
|
-
logger.level = Logger::INFO
|
188
|
-
else
|
189
|
-
logger.level = Logger::WARN
|
190
|
-
end
|
191
|
-
|
192
107
|
p = Process.fork do
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
end
|
199
|
-
|
200
|
-
@command_processes = {}
|
201
|
-
@threads = {}
|
202
|
-
stop_loop = false
|
203
|
-
|
204
|
-
Signal.trap('HUP', 'IGNORE')
|
108
|
+
#Some Setup Work
|
109
|
+
$0="WebApp Worker - Job File: #{@file}"
|
110
|
+
waw_system = WebappWorker::System.new
|
111
|
+
waw_system.setup(debug,verbose)
|
112
|
+
logger = waw_system.logger
|
205
113
|
|
206
114
|
%w(INT QUIT TERM TSTP).each do |sig|
|
207
115
|
Signal.trap(sig) do
|
116
|
+
stop_loop = true
|
208
117
|
logger.warn "Received a #{sig} signal, stopping current commands."
|
209
|
-
|
118
|
+
waw_system.graceful_termination(@threads,@command_processes)
|
210
119
|
end
|
211
120
|
end
|
212
121
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
logger.info "Received USR1 signal, sent version: #{version}"
|
218
|
-
end
|
219
|
-
|
220
|
-
Signal.trap('USR2') do
|
221
|
-
logger.level = Logger::DEBUG
|
222
|
-
puts
|
223
|
-
puts "Changed logger level to Debug"
|
224
|
-
logger.info "Changed logger level to Debug"
|
225
|
-
end
|
226
|
-
|
227
|
-
#Signal.trap('STOP') do |s|
|
228
|
-
# #Stop Looping until
|
229
|
-
# stop_loop = true
|
230
|
-
# logger.warn "Received signal #{s}, pausing current loop."
|
231
|
-
#end
|
232
|
-
#
|
233
|
-
#Signal.trap('CONT') do
|
234
|
-
# #Start Looping again (catch throw?)
|
235
|
-
# stop_loop = false
|
236
|
-
# logger.warn "Received signal #{s}, starting current loop."
|
237
|
-
#end
|
122
|
+
#WebApp Worker is setup now do the real work
|
123
|
+
@command_processes = {}
|
124
|
+
@threads = {}
|
125
|
+
stop_loop = false
|
238
126
|
|
239
127
|
logger.debug "Going into Loop"
|
240
128
|
until stop_loop
|
@@ -263,6 +151,8 @@ module WebappWorker
|
|
263
151
|
pid, stdin, stdout, stderr = Open4::popen4 command
|
264
152
|
@command_processes.store(pid,command)
|
265
153
|
|
154
|
+
#make logger log to a specific job file log file
|
155
|
+
|
266
156
|
ignored, status = Process::waitpid2 pid
|
267
157
|
|
268
158
|
if status.to_i == 0
|
@@ -299,6 +189,5 @@ module WebappWorker
|
|
299
189
|
|
300
190
|
Process.detach(p)
|
301
191
|
end
|
302
|
-
|
303
192
|
end
|
304
193
|
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'drb'
|
2
|
+
require 'etc'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module WebappWorker
|
6
|
+
class System
|
7
|
+
|
8
|
+
attr_accessor :user, :tmp_dir, :pid_file, :ipc_file, :logger
|
9
|
+
|
10
|
+
def initialize(user_supplied_hash={})
|
11
|
+
standard_hash = { user:"nobody", tmp_dir:"/tmp/webapp_worker/", pid_file:"/tmp/webapp_worker/waw.pid", ipc_file:"/tmp/webapp_worker/waw", logger:"" }
|
12
|
+
|
13
|
+
user_supplied_hash = {} unless user_supplied_hash
|
14
|
+
user_supplied_hash = standard_hash.merge(user_supplied_hash)
|
15
|
+
|
16
|
+
user_supplied_hash.each do |key,value|
|
17
|
+
self.instance_variable_set("@#{key}", value)
|
18
|
+
self.class.send(:define_method, key, proc{self.instance_variable_get("@#{key}")})
|
19
|
+
self.class.send(:define_method, "#{key}=", proc{|x| self.instance_variable_set("@#{key}", x)})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.process_alive?(pid)
|
24
|
+
begin
|
25
|
+
Process.kill(0, pid.to_i)
|
26
|
+
true
|
27
|
+
rescue Errno::ESRCH
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup(debug=nil,verbose=nil)
|
33
|
+
self.check_for_directory
|
34
|
+
self.create_logger(debug,verbose)
|
35
|
+
self.check_for_process
|
36
|
+
self.start_listening
|
37
|
+
|
38
|
+
Signal.trap('HUP', 'IGNORE')
|
39
|
+
|
40
|
+
Signal.trap('USR1') do
|
41
|
+
version = WebappWorker::VERSION
|
42
|
+
puts
|
43
|
+
puts "Webapp Worker Version: #{version}"
|
44
|
+
logger.info "Received USR1 signal, sent version: #{version}"
|
45
|
+
end
|
46
|
+
|
47
|
+
Signal.trap('USR2') do
|
48
|
+
logger.level = Logger::DEBUG
|
49
|
+
puts
|
50
|
+
puts "Changed logger level to Debug"
|
51
|
+
logger.info "Changed logger level to Debug"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def check_for_directory
|
56
|
+
if Dir.exists?(@tmp_dir)
|
57
|
+
else
|
58
|
+
Dir.mkdir(@tmp_dir, 0700)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_logger(debug=nil,verbose=nil)
|
63
|
+
@logger = Logger.new("#{@tmp_dir}waw.log", 5, 5242880)
|
64
|
+
|
65
|
+
if debug
|
66
|
+
@logger.level = Logger::DEBUG
|
67
|
+
elsif verbose
|
68
|
+
@logger.level = Logger::INFO
|
69
|
+
else
|
70
|
+
@logger.level = Logger::WARN
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def delete_files
|
75
|
+
@logger.fatal "Deleting both PID and IPC files"
|
76
|
+
|
77
|
+
begin
|
78
|
+
File.delete(@pid_file)
|
79
|
+
@logger.fatal "Deleted PID File: #{@pid_file}"
|
80
|
+
rescue => error
|
81
|
+
@logger.fatal "Error at Deleting PID File: #{@pid_file}: #{error}"
|
82
|
+
end
|
83
|
+
|
84
|
+
begin
|
85
|
+
File.delete(@ipc_file)
|
86
|
+
@logger.fatal "Deleted IPC File: #{@ipc_file}"
|
87
|
+
rescue => error
|
88
|
+
@logger.fatal "Error at Deleting IPC File: #{@ipc_file}: #{error}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def create_pid
|
93
|
+
self.delete_files
|
94
|
+
|
95
|
+
@logger.info "Creating Pid File at #{@pid_file}"
|
96
|
+
File.open(@pid_file, 'w') { |f| f.write(Process.pid) }
|
97
|
+
@logger.info "Pid File created: #{Process.pid} at #{@pid_file}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def check_for_process
|
101
|
+
if File.exists?(@pid_file)
|
102
|
+
possible_pid = ""
|
103
|
+
pf = File.open(@pid_file, 'r').each { |f| possible_pid+= f }
|
104
|
+
pf.close
|
105
|
+
|
106
|
+
if WebappWorker::System.process_alive?(possible_pid)
|
107
|
+
version = self.check_process_version
|
108
|
+
my_version = WebappWorker::VERSION
|
109
|
+
|
110
|
+
if version.to_s == my_version.to_s
|
111
|
+
puts "Already found webapp_worker running, pid is: #{possible_pid}, exiting..."
|
112
|
+
@logger.fatal "Found webapp_worker already running with pid: #{possible_pid}, Pid File: #{@pid_file} exiting..."
|
113
|
+
exit 1
|
114
|
+
else
|
115
|
+
puts "Found old version of webapp_worker #{version}, running with pid: #{possible_pid}, asking it to terminate since my version is: #{my_version}"
|
116
|
+
@logger.fatal "Found old version of webapp_worker #{version}, running with pid: #{possible_pid}, asking it to terminate since my version is: #{my_version}"
|
117
|
+
|
118
|
+
Process.kill("INT",possible_pid.to_i)
|
119
|
+
|
120
|
+
while WebappWorker::System.process_alive?(possible_pid)
|
121
|
+
sleep 120
|
122
|
+
|
123
|
+
begin
|
124
|
+
Process.kill("KILL",possible_pid.to_i)
|
125
|
+
rescue => error
|
126
|
+
end
|
127
|
+
|
128
|
+
self.create_pid
|
129
|
+
end
|
130
|
+
end
|
131
|
+
else
|
132
|
+
@logger.warn "Found pid file, but no process running"
|
133
|
+
self.create_pid
|
134
|
+
end
|
135
|
+
else
|
136
|
+
@logger.info "Did not find a pid file"
|
137
|
+
self.create_pid
|
138
|
+
end
|
139
|
+
|
140
|
+
@logger.info "Starting Webapp Worker"
|
141
|
+
end
|
142
|
+
|
143
|
+
def start_listening
|
144
|
+
@logger.info "Starting to listen on IPC: #{@ipc_file}"
|
145
|
+
|
146
|
+
DRb.start_service("drbunix:#{@ipc_file}", WebappWorker::VERSION)
|
147
|
+
|
148
|
+
@logger.info "Now listenting on IPC: #{@ipc_file}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def check_process_version
|
152
|
+
@logger.info "Asking the processes version from IPC: #{@ipc_file}"
|
153
|
+
|
154
|
+
DRb.start_service
|
155
|
+
version = DRbObject.new_with("drbunix:#{@ipc_file}", nil)
|
156
|
+
|
157
|
+
@logger.info "The process' version is: #{version}"
|
158
|
+
return version
|
159
|
+
end
|
160
|
+
|
161
|
+
def graceful_termination(threads,command_processes)
|
162
|
+
begin
|
163
|
+
puts
|
164
|
+
puts "Graceful Termination started, waiting 60 seconds before KILL signal send"
|
165
|
+
@logger.info "Graceful Termination started, waiting 60 seconds before KILL signal send"
|
166
|
+
|
167
|
+
Timeout::timeout(60) do
|
168
|
+
command_processes.each do |pid,command|
|
169
|
+
@logger.debug "Sending INT Signal to #{command} Process with PID: #{pid}"
|
170
|
+
|
171
|
+
if WebappWorker::System.process_alive?(pid)
|
172
|
+
Process.kill("INT",pid.to_i)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
threads.each do |thread,command|
|
177
|
+
thread.join
|
178
|
+
end
|
179
|
+
end
|
180
|
+
rescue Timeout::Error
|
181
|
+
puts "Graceful Termination bypassed, killing processes and threads"
|
182
|
+
@logger.info "Graceful Termination bypassed, killing processes and threads"
|
183
|
+
|
184
|
+
command_processes.each do |pid,command|
|
185
|
+
@logger.debug "Killing #{command} Process with PID: #{pid}"
|
186
|
+
|
187
|
+
if WebappWorker::System.process_alive?(pid)
|
188
|
+
Process.kill("KILL",pid.to_i)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
threads.each do |thread,command|
|
193
|
+
@logger.debug "Killing Command Thread: #{command}"
|
194
|
+
Thread.kill(thread)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
puts "Stopping Webapp Worker"
|
199
|
+
@logger.info "Stopping Webapp Worker"
|
200
|
+
|
201
|
+
self.delete_files
|
202
|
+
exit 0
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webapp_worker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-18 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: trollop
|
16
|
-
requirement: &
|
16
|
+
requirement: &80202920 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.16.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *80202920
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: open4
|
27
|
-
requirement: &
|
27
|
+
requirement: &80201930 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 1.3.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *80201930
|
36
36
|
description: Allow the webapp to handle your workers, no need to use a job scheduler
|
37
37
|
email:
|
38
38
|
- nickwillever@gmail.com
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- lib/webapp_worker.rb
|
50
50
|
- lib/webapp_worker/application.rb
|
51
51
|
- lib/webapp_worker/job.rb
|
52
|
+
- lib/webapp_worker/system.rb
|
52
53
|
- lib/webapp_worker/version.rb
|
53
54
|
- webapp_worker.gemspec
|
54
55
|
homepage: https://nictrix.github.com/webapp_worker
|