Let's say this is my worker:
class FooWorker
@queue = :foo
def self.perform
User.all.each do |u|
...
Do Long Operations (Unsafe to kill)
...
# Here it's safe to break the worker and restart
end
end
end
I'm enqueing this with Resque Scheduler and this is my Bluepill conf:
...
app.process(process_name) do |process|
process.group = "resque"
process.start_command = "rake environment resque:work QUEUE=foo RAILS_ENV=production"
...
process.stop_signals = [:quit, 5.seconds, :term, 1.minute, :kill]
process.daemonize = true
process.start_grace_time = 30.seconds
process.stop_grace_time = 80.seconds
process.monitor_children do |child_process|
child_process.stop_command = "kill -QUIT {{PID}}"
child_process.checks :mem_usage, :every => 30.seconds, :below => 500.megabytes, :times => [3,4], :fires => :stop
end
end
....
I'd like to make Bluepill or Resque wait until it reaches the "safe" block to restart or shut down. How to achieve this?
Try it this way:
1) Set resque to kill children gracefully on TERM/INT with
new_kill_child
method by settingTERM_CHILD
andRESQUE_TERM_TIMEOUT
env variables on start:Default value for
RESQUE_TERM_TIMEOUT
is 4 seconds.This will make resque send TERM signal to child, wait for
RESQUE_TERM_TIMEOUT
and if child is still running, kill it. Be sure toa) set this timeout large enough for your critical section to end,
b) configure Bluepill TERM timeout in
process.stop_signals
to be a bit larger thanRESQUE_TERM_TIMEOUT
not to kill worker while it waits for child process to end critical section.2) Handle TERM signal in child process to stop gracefully: