Skip to content

Commit 1504042

Browse files
author
Nick Kallen
committed
fix for a very subtle race condition
hard to test
1 parent 0385256 commit 1504042

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

lib/cash/accessor.rb

+7-5
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,25 @@ def get(keys, options = {}, &block)
3838
end
3939

4040
def add(key, value, options = {})
41-
repository.add(cache_key(key), value, options[:ttl] || 0, options[:raw])
41+
if repository.add(cache_key(key), value, options[:ttl] || 0, options[:raw]) == "NOT_STORED\r\n"
42+
yield
43+
end
4244
end
4345

4446
def set(key, value, options = {})
4547
repository.set(cache_key(key), value, options[:ttl] || 0, options[:raw])
4648
end
4749

4850
def incr(key, delta = 1, ttl = 0)
49-
repository.incr(cache_key(key), delta) || begin
50-
repository.add(cache_key(key), (result = yield).to_s, ttl, true)
51+
repository.incr(cache_key = cache_key(key), delta) || begin
52+
repository.add(cache_key, (result = yield).to_s, ttl, true) { repository.incr(cache_key) }
5153
result
5254
end
5355
end
5456

5557
def decr(key, delta = 1, ttl = 0)
56-
repository.decr(cache_key(key), delta) || begin
57-
repository.add(cache_key(key), (result = yield).to_s, ttl, true)
58+
repository.decr(cache_key = cache_key(key), delta) || begin
59+
repository.add(cache_key, (result = yield).to_s, ttl, true) { repository.decr(cache_key) }
5860
result
5961
end
6062
end

spec/cash/accessor_spec.rb

+16
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ module Cash
101101
end
102102
end
103103
end
104+
105+
describe '#add' do
106+
describe 'when the value already exists' do
107+
it 'yields to the block' do
108+
Story.set("count", 1)
109+
Story.add("count", 1) { "yield me" }.should == "yield me"
110+
end
111+
end
112+
113+
describe 'when the value does not already exist' do
114+
it 'adds the key to the cache' do
115+
Story.add("count", 1)
116+
Story.get("count").should == 1
117+
end
118+
end
119+
end
104120

105121
describe '#decr' do
106122
describe 'when there is a cache hit' do

0 commit comments

Comments
 (0)