diff --git a/lib/resque/plugins/lock_timeout.rb b/lib/resque/plugins/lock_timeout.rb index e1d893d..2d7f33f 100644 --- a/lib/resque/plugins/lock_timeout.rb +++ b/lib/resque/plugins/lock_timeout.rb @@ -297,7 +297,12 @@ def around_perform_lock(*args) end end + def on_failure_lock(exception, *args) + # In case of a DirtyExit, the ensure block of the around hook is not called + if exception.is_a?(Resque::DirtyExit) + release_lock!(*args) + end + end end - end end diff --git a/test/lock_test.rb b/test/lock_test.rb index 53fb81a..167d4d2 100644 --- a/test/lock_test.rb +++ b/test/lock_test.rb @@ -65,6 +65,20 @@ def test_lock_is_released_on_failure assert_equal false, FastJob.locked?, 'lock should have been released' end + if Process.respond_to?(:fork) && Gem::Version.new(Resque::VERSION) >= Gem::Version.new('1.20.0') + def test_lock_is_released_on_dirty_exit + Resque.enqueue(FailingKilledJob) + job = @worker.reserve + child = fork do + Resque.redis.client.reconnect + job.perform + end + Process.waitpid(child) + job.fail(Resque::DirtyExit.new) + assert_equal false, FailingKilledJob.locked?, 'lock should have been released' + end + end + def test_can_acquire_lock_with_timeout now = Time.now.to_i assert SlowWithTimeoutJob.acquire_lock!, 'acquire lock' diff --git a/test/test_jobs.rb b/test/test_jobs.rb index e5ed862..2f1213e 100644 --- a/test/test_jobs.rb +++ b/test/test_jobs.rb @@ -38,6 +38,16 @@ def self.perform end end +# Job that fails with a SIGKILL +class FailingKilledJob + extend Resque::Plugins::LockTimeout + @queue = :test + + def self.perform + Process.kill("KILL", Process.pid) + end +end + # Job that enables the timeout algorithm. class SlowWithTimeoutJob extend Resque::Plugins::LockTimeout