New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/avoid deregistering when running at exit hooks #1017

Merged
merged 7 commits into from Jun 2, 2013
View
@@ -183,14 +183,18 @@ def work(interval = 5.0, &block)
job.fail(DirtyExit.new($?.to_s)) if $?.signaled?
else
unregister_signal_handlers if will_fork? && term_child
begin
reconnect
perform(job, &block)
reconnect
perform(job, &block)
if will_fork?
run_at_exit_hooks ? exit : exit!
rescue Exception => exception
report_failed_job(job,exception)
end
do_exit_or_exit!
end
done_working
@child = nil
else
@@ -208,6 +212,16 @@ def work(interval = 5.0, &block)
unregister_worker(exception)
end
def do_exit_or_exit!
return unless will_fork?
exit! unless run_at_exit_hooks
begin
exit
rescue SystemExit
nil
end
end
# DEPRECATED. Processes a single job. If none is given, it will
# try to produce one. Usually run in the child.
def process(job = nil, &block)
@@ -220,19 +234,28 @@ def process(job = nil, &block)
done_working
end
# Reports the exception and marks the job as failed
def report_failed_job(job,exception)
log "#{job.inspect} failed: #{exception.inspect}"
begin
job.fail(exception)
rescue Object => exception
log "Received exception when reporting failure: #{exception.inspect}"
end
begin
failed!
rescue Object => exception
log "Received exception when increasing failed jobs counter (redis issue) : #{exception.inspect}"
end
end
# Processes a given job in the child.
def perform(job)
begin
run_hook :after_fork, job if will_fork?
job.perform
rescue Object => e
log "#{job.inspect} failed: #{e.inspect}"
begin
job.fail(e)
rescue Object => e
log "Received exception when reporting failure: #{e.inspect}"
end
failed!
report_failed_job(job,e)
else
log "done: #{job.inspect}"
ensure
View
@@ -72,6 +72,38 @@
end
class ::RaiseExceptionOnFailure
def self.on_failure_trhow_exception(exception,*args)
$TESTING = true
raise "The worker threw an exception"
end
def self.perform
""
end
end
test "should not treat SystemExit as an exception in the child with run_at_exit_hooks == true" do
if worker_pid = Kernel.fork
Process.waitpid(worker_pid)
else
# ensure we actually fork
$TESTING = false
Resque.redis.client.reconnect
Resque::Job.create(:not_failing_job, RaiseExceptionOnFailure)
worker = Resque::Worker.new(:not_failing_job)
worker.run_at_exit_hooks = true
suppress_warnings do
worker.work(0)
end
exit
end
end
test "does not execute at_exit hooks by default" do
tmpfile = File.join(Dir.tmpdir, "resque_at_exit_test_file")
FileUtils.rm_f tmpfile
@@ -624,7 +656,7 @@ def self.perform
assert_not_equal original_connection, Resque.redis.client.connection.instance_variable_get("@sock")
end
test "tries to reconnect three times before giving up" do
test "tries to reconnect three times before giving up and the failure does not unregister the parent" do
begin
class Redis::Client
alias_method :original_reconnect, :reconnect
@@ -649,6 +681,9 @@ def sleep(duration = nil)
assert_equal 3, stdout.scan(/retrying/).count
assert_equal 1, stdout.scan(/quitting/).count
assert_equal 0, stdout.scan(/Failed to start worker/).count
assert_equal 1, stdout.scan(/Redis::BaseConnectionError: Redis::BaseConnectionError/).count
ensure
class Redis::Client
alias_method :reconnect, :original_reconnect
ProTip! Use n and p to navigate between commits in a pull request.