From 5c18f69ef05a92e604f097ea9e4bc7288a694f2a Mon Sep 17 00:00:00 2001 From: Jan Kmet Date: Fri, 12 Jun 2015 12:30:05 +0200 Subject: [PATCH 1/2] lock_expiration split character changed to ';' --- lib/redis/lock.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/redis/lock.rb b/lib/redis/lock.rb index 25c8531..42a06a3 100644 --- a/lib/redis/lock.rb +++ b/lib/redis/lock.rb @@ -39,7 +39,7 @@ def lock(key, timeout = 60, max_attempts = 100) return true else current_lock = self.get(current_lock_key) - if (current_lock.to_s.split('-').first.to_i) < Time.now.to_i + if (current_lock.to_s.split(';').first.to_i) < Time.now.to_i compare_value = self.getset(current_lock_key, expiration_value) return true if compare_value == current_lock end @@ -62,7 +62,7 @@ def unlock(key) current_lock_key = lock_key(key) lock_value = self.get(current_lock_key) return true unless lock_value - lock_timeout, lock_process, lock_thread = lock_value.split('-') + lock_timeout, lock_process, lock_thread = lock_value.split(';') if (lock_timeout.to_i > Time.now.to_i) && (lock_process.to_i == Process.pid) && lock_thread.to_i == Thread.current.object_id self.del(current_lock_key) return true @@ -74,7 +74,7 @@ def unlock(key) private def lock_expiration(timeout) - "#{Time.now.to_i + timeout + 1}-#{Process.pid}-#{Thread.current.object_id}" + "#{Time.now.to_i + timeout + 1};#{Process.pid};#{Thread.current.object_id}" end def lock_key(key) From 4917160e4d7323a7a089e54499e79e49b8e8f708 Mon Sep 17 00:00:00 2001 From: Jan Kmet Date: Mon, 15 Jun 2015 10:27:47 +0200 Subject: [PATCH 2/2] some additional tests --- spec/redis_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/redis_spec.rb b/spec/redis_spec.rb index 9d26f48..8b29d02 100644 --- a/spec/redis_spec.rb +++ b/spec/redis_spec.rb @@ -65,5 +65,16 @@ # Should have spent 1 second trying to lock DateTime.now.should >= time + Rational(1, 86400) end + + it "should not unlock a key from another thread" do + @redis.lock('test_key').should be_true + Thread.new { @redis.unlock('test_key').should_not be_true }.join + end + + it "should not unlock a key from another process" do + fork { @redis.lock('test_key'); exit 0 } + Process.wait2 + @redis.unlock('test_key').should_not be_true + end end \ No newline at end of file