Skip to content

Commit f931734

Browse files
committed
Merge pull request #1 from ridecharge/expiring_locks
Add support for an expiration option.
2 parents d935ee4 + 21520c8 commit f931734

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

lib/redis/semaphore.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Semaphore
1515
# Redis::Semaphore.new(:my_semaphore, :path => "bla")
1616
def initialize(name, opts = {})
1717
@name = name
18+
@expiration = opts.delete(:expiration)
1819
@resource_count = opts.delete(:resources) || 1
1920
@stale_client_timeout = opts.delete(:stale_client_timeout)
2021
@redis = opts.delete(:redis) || Redis.new(opts)
@@ -30,6 +31,7 @@ def exists_or_create!
3031
elsif token != API_VERSION
3132
raise "Semaphore exists but running as wrong version (version #{token} vs #{API_VERSION})."
3233
else
34+
set_expiration
3335
true
3436
end
3537
end
@@ -80,7 +82,7 @@ def locked?(token = nil)
8082
@tokens.each do |token|
8183
return true if locked?(token)
8284
end
83-
85+
8486
false
8587
end
8688
end
@@ -150,10 +152,17 @@ def create!
150152
@resource_count.times do |index|
151153
@redis.rpush(available_key, index)
152154
end
153-
154155
# Persist key
155156
@redis.del(exists_key)
156157
@redis.set(exists_key, API_VERSION)
158+
set_expiration
159+
end
160+
end
161+
162+
def set_expiration
163+
if @expiration
164+
@redis.expire(available_key, @expiration)
165+
@redis.expire(exists_key, @expiration)
157166
end
158167
end
159168

spec/semaphore_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,20 @@
114114
end
115115
end
116116

117+
describe "semaphore with expiration" do
118+
let(:semaphore) { Redis::Semaphore.new(:my_semaphore, :redis => @redis, :expiration => 2) }
119+
let(:multisem) { Redis::Semaphore.new(:my_semaphore_2, :resources => 2, :redis => @redis, :expiration => 2) }
120+
121+
it_behaves_like "a semaphore"
122+
123+
it "expires keys" do
124+
original_key_size = @redis.keys.count
125+
semaphore.exists_or_create!
126+
sleep 3.0
127+
expect(@redis.keys.count).to eq(original_key_size)
128+
end
129+
end
130+
117131
describe "semaphore without staleness checking" do
118132
let(:semaphore) { Redis::Semaphore.new(:my_semaphore, :redis => @redis) }
119133
let(:multisem) { Redis::Semaphore.new(:my_semaphore_2, :resources => 2, :redis => @redis) }

0 commit comments

Comments
 (0)