Skip to content

Commit 23bd45e

Browse files
author
Jon Calvert
committed
Remove the extraneous expire during create, since the subsequent persist will obviate it anyway and since keys can expire during a MULTI transaction anyway. Return the removed statement where we always reset the key expiration prior to attempting to obtain a lock. This prevents the orphaned EXISTS key that never expires.
1 parent 9c580db commit 23bd45e

File tree

2 files changed

+12
-14
lines changed

2 files changed

+12
-14
lines changed

lib/redis/semaphore.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def exists_or_create!
3636
if token == API_VERSION && @redis.get(version_key).nil?
3737
@redis.set(version_key, API_VERSION)
3838
end
39-
39+
set_expiration_if_necessary
4040
true
4141
end
4242
end
@@ -59,7 +59,6 @@ def delete!
5959
def lock(timeout = 0)
6060
exists_or_create!
6161
release_stale_locks! if check_staleness?
62-
6362
token_pair = @redis.blpop(available_key, timeout)
6463
return false if token_pair.nil?
6564

@@ -157,8 +156,6 @@ def simple_mutex(key_name, expires = nil)
157156
end
158157

159158
def create!
160-
@redis.expire(exists_key, 10)
161-
162159
@redis.multi do
163160
@redis.del(grabbed_key)
164161
@redis.del(available_key)
@@ -167,7 +164,6 @@ def create!
167164
end
168165
@redis.set(version_key, API_VERSION)
169166
@redis.persist(exists_key)
170-
171167
set_expiration_if_necessary
172168
end
173169
end

spec/semaphore_spec.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,25 @@
149149
expect(@redis.keys.count).to eq(original_key_size)
150150
end
151151

152-
it "does not leave an exists key without an expiration when an expiration is specified" do
153-
original_key_size = @redis.keys.count
152+
it "does not leave a key without expiration if expiration given" do
154153
queue = Queue.new
155-
threads = 2.times.collect do
154+
threads = 2.times.map do
156155
Thread.new do
157-
Redis::Semaphore.new(:my_semaphore, :redis => @redis, :expiration => 3).lock(5) do
156+
opts = { redis: @redis, expiration: 3 }
157+
Redis::Semaphore.new(:my_semaphore, opts).lock(5) do
158158
sleep 1
159159
end
160160
end
161161
end
162162
sleep 4.0
163-
@redis2 = Redis.new :db => 15
164-
threads.each{|t| t.kill } #ensure signal step fails
165-
expect(@redis2.ttl("SEMAPHORE:my_semaphore:EXISTS").to_s).to_not eql("-1")
166-
sleep 4.0 #allow blpop timeout to occur
163+
@redis2 = Redis.new db: 15
164+
threads.each(&:kill) # ensure signal step fails
165+
exist_key = @redis2.ttl("SEMAPHORE:my_semaphore:EXISTS").to_s
166+
expect(exist_key).to_not eql("-1")
167+
sleep 4.0 # allow blpop timeout to occur
167168
thrd = Thread.new do
168-
Redis::Semaphore.new(:my_semaphore, :redis => @redis2, :expiration => 3).lock(5) do
169+
opts = { redis: @redis2, expiration: 3 }
170+
Redis::Semaphore.new(:my_semaphore, opts).lock(5) do
169171
queue << "work"
170172
end
171173
end

0 commit comments

Comments
 (0)