Skip to content

Commit b3ea3c4

Browse files
committed
Merge pull request resque#666 from ecoffey/pause_hooks
Add before_pause and after_pause as Resque worker hooks
2 parents 0102eee + 3628a6f commit b3ea3c4

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

docs/HOOKS.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ The `after_fork` hook will be run in the child process and is passed
3838
the current job. Any changes you make, therefor, will only live as
3939
long as the job currently being processes.
4040

41+
You can also run a hook both before a worker pauses (`before_pause`),
42+
and after it is paused (`after_pause`). In each case the block will be
43+
passed the worker that is pausing or unpausing, respectively:
44+
45+
Resque.before_pause do |worker|
46+
puts "It looks like #{worker} is now paused!"
47+
end
48+
49+
Resque.after_pause do |worker|
50+
puts "Whew, back to work for #{worker}!"
51+
end
52+
4153
All worker hooks can also be set using a setter, e.g.
4254

4355
Resque.after_fork = proc { puts "called" }

lib/resque.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,26 @@ def after_fork(&block)
121121
# Set the after_fork proc.
122122
attr_writer :after_fork
123123

124+
# The `before_pause` hook will be run in the parent process before the
125+
# worker has paused processing (via #pause_processing or SIGUSR2).
126+
def before_pause(&block)
127+
@before_pause = block if block_given?
128+
@before_pause
129+
end
130+
131+
# Set the after_pause proc.
132+
attr_writer :before_pause
133+
134+
# The `after_pause` hook will be run in the parent process after the
135+
# worker has paused (via SIGCONT).
136+
def after_pause(&block)
137+
@after_pause = block if block_given?
138+
@after_pause
139+
end
140+
141+
# Set the after_continue proc.
142+
attr_writer :after_pause
143+
124144
def to_s
125145
"Resque Client connected to #{redis_id}"
126146
end

lib/resque/worker.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,10 @@ def pause
361361
wr.write 'x'
362362
wr.close
363363
}
364+
run_hook :before_pause, self
364365
rd.read 1
365366
rd.close
367+
run_hook :after_pause, self
366368
end
367369

368370
# Stop processing jobs after the current one has completed (if we're

test/worker_test.rb

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ def self.perform
479479
it "returns PID of running process" do
480480
assert_equal @worker.to_s.split(":")[1].to_i, @worker.pid
481481
end
482-
482+
483483
it "requeue failed queue" do
484484
queue = 'good_job'
485485
Resque::Failure.create(:exception => Exception.new, :worker => Resque::Worker.new(queue), :queue => queue, :payload => {'class' => 'GoodJob'})
@@ -506,6 +506,52 @@ def self.perform
506506
assert_not_equal original_connection, Resque.redis.client.connection.instance_variable_get("@sock")
507507
end
508508

509+
it "will call before_pause before it is paused" do
510+
before_pause_called = false
511+
captured_worker = nil
512+
513+
Resque.before_pause do |worker|
514+
before_pause_called = true
515+
captured_worker = worker
516+
end
517+
518+
@worker.pause_processing
519+
520+
assert !before_pause_called
521+
522+
t = Thread.start { sleep(0.1); Process.kill('CONT', @worker.pid) }
523+
524+
@worker.work(0)
525+
526+
t.join
527+
528+
assert before_pause_called
529+
assert_equal @worker, captured_worker
530+
end
531+
532+
it "will call after_pause after it is paused" do
533+
after_pause_called = false
534+
captured_worker = nil
535+
536+
Resque.after_pause do |worker|
537+
after_pause_called = true
538+
captured_worker = worker
539+
end
540+
541+
@worker.pause_processing
542+
543+
assert !after_pause_called
544+
545+
t = Thread.start { sleep(0.1); Process.kill('CONT', @worker.pid) }
546+
547+
@worker.work(0)
548+
549+
t.join
550+
551+
assert after_pause_called
552+
assert_equal @worker, captured_worker
553+
end
554+
509555
if !defined?(RUBY_ENGINE) || defined?(RUBY_ENGINE) && RUBY_ENGINE != "jruby"
510556
[SignalException, Resque::TermException].each do |exception|
511557
{

0 commit comments

Comments
 (0)