From c731d1f93c88d537698700652e13e4957a662425 Mon Sep 17 00:00:00 2001 From: Tatsuhiko Miyagawa Date: Wed, 9 Jan 2013 16:34:14 -0800 Subject: [PATCH 1/5] relax resque dependency --- resque-lonely_job.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resque-lonely_job.gemspec b/resque-lonely_job.gemspec index 54a7d61..933237a 100644 --- a/resque-lonely_job.gemspec +++ b/resque-lonely_job.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |gem| gem.require_paths = ["lib"] gem.version = Resque::Plugins::LonelyJob::VERSION - gem.add_dependency 'resque', '~> 1.20.0' + gem.add_dependency 'resque', '>= 1.20.0' gem.add_development_dependency 'mock_redis', '~> 0.4.1' gem.add_development_dependency 'rake' gem.add_development_dependency 'rspec' From b7ce63e13d851b02dbaf4fdb0e94dc737f6e2fbf Mon Sep 17 00:00:00 2001 From: Tatsuhiko Miyagawa Date: Sun, 20 Jan 2013 16:53:11 -0800 Subject: [PATCH 2/5] save integer value of the lock --- lib/resque-lonely_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque-lonely_job.rb b/lib/resque-lonely_job.rb index ce29cad..e7d8400 100644 --- a/lib/resque-lonely_job.rb +++ b/lib/resque-lonely_job.rb @@ -6,7 +6,7 @@ module LonelyJob LOCK_TIMEOUT = 60 * 60 * 24 * 5 # 5 days def lock_timeout - Time.now.utc + LOCK_TIMEOUT + 1 + Time.now.to_i + LOCK_TIMEOUT + 1 end # Overwrite this method to uniquely identify which mutex should be used From 8ab67f6aaff3fd7c725f30d146ea3ddc791bb852 Mon Sep 17 00:00:00 2001 From: Tatsuhiko Miyagawa Date: Sun, 20 Jan 2013 17:17:13 -0800 Subject: [PATCH 3/5] Implement locking timeout per SETNX design pattern at http://redis.io/commands/setnx --- lib/resque-lonely_job.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/resque-lonely_job.rb b/lib/resque-lonely_job.rb index e7d8400..04742f6 100644 --- a/lib/resque-lonely_job.rb +++ b/lib/resque-lonely_job.rb @@ -16,7 +16,15 @@ def redis_key(*args) end def can_lock_queue?(*args) - Resque.redis.setnx(redis_key(*args), lock_timeout) + now = Time.now.to_i + key = redis_key(*args) + timeout = lock_timeout + + # Per http://redis.io/commands/getset + return true if Resque.redis.setnx(key, timeout) + return false if Resque.redis.get(key).to_i > now + return true if Resque.redis.getset(key, timeout).to_i <= now + return false end def unlock_queue(*args) From f8791b12746fe1e62bfbf672d3db8e5a34789227 Mon Sep 17 00:00:00 2001 From: Tatsuhiko Miyagawa Date: Mon, 21 Jan 2013 17:38:47 -0800 Subject: [PATCH 4/5] fix link in the comment --- lib/resque-lonely_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque-lonely_job.rb b/lib/resque-lonely_job.rb index 04742f6..11ee9bd 100644 --- a/lib/resque-lonely_job.rb +++ b/lib/resque-lonely_job.rb @@ -20,7 +20,7 @@ def can_lock_queue?(*args) key = redis_key(*args) timeout = lock_timeout - # Per http://redis.io/commands/getset + # Per http://redis.io/commands/setnx return true if Resque.redis.setnx(key, timeout) return false if Resque.redis.get(key).to_i > now return true if Resque.redis.getset(key, timeout).to_i <= now From 6bfac4294ab975a91a2a95c5ce669fbd627a5365 Mon Sep 17 00:00:00 2001 From: Tatsuhiko Miyagawa Date: Wed, 23 Jan 2013 10:14:35 -0800 Subject: [PATCH 5/5] Added spec to test setnx/getset unlock expired lock behavior --- resque-lonely_job.gemspec | 1 + spec/lib/lonely_job_spec.rb | 31 +++++++++++++++++++++++++++++++ spec/spec_helper.rb | 1 + 3 files changed, 33 insertions(+) diff --git a/resque-lonely_job.gemspec b/resque-lonely_job.gemspec index 933237a..9d78dae 100644 --- a/resque-lonely_job.gemspec +++ b/resque-lonely_job.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |gem| gem.add_development_dependency 'rake' gem.add_development_dependency 'rspec' gem.add_development_dependency 'debugger' + gem.add_development_dependency 'timecop' gem.description = <