Skip to content

Commit 4626c66

Browse files
authored
Merge pull request #188 from rails/unless-exist
Support unless_exist
2 parents c96b69c + 6a0b3d5 commit 4626c66

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
lines changed

app/models/solid_cache/entry.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def lock_and_write(key, &block)
5252
uncached do
5353
result = lock.where(key_hash: key_hash_for(key)).pick(:key, :value)
5454
new_value = block.call(result&.first == key ? result[1] : nil)
55-
write(key, new_value)
55+
write(key, new_value) if new_value
5656
new_value
5757
end
5858
end

lib/solid_cache/store/api.rb

+17-6
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,27 @@ def read_serialized_entry(key, **options)
3939
entry_read(key)
4040
end
4141

42-
def write_entry(key, entry, raw: false, **options)
42+
def write_entry(key, entry, raw: false, unless_exist: false, **options)
4343
payload = serialize_entry(entry, raw: raw, **options)
44-
# No-op for us, but this writes it to the local cache
45-
write_serialized_entry(key, payload, raw: raw, **options)
4644

47-
entry_write(key, payload)
45+
if unless_exist
46+
written = false
47+
entry_lock_and_write(key) do |value|
48+
if value.nil? || deserialize_entry(value, **options).expired?
49+
written = true
50+
payload
51+
end
52+
end
53+
else
54+
written = entry_write(key, payload)
55+
end
56+
57+
write_serialized_entry(key, payload, raw: raw, returning: written, **options)
58+
written
4859
end
4960

50-
def write_serialized_entry(key, payload, raw: false, unless_exist: false, expires_in: nil, race_condition_ttl: nil, **options)
51-
true
61+
def write_serialized_entry(key, payload, raw: false, unless_exist: false, expires_in: nil, race_condition_ttl: nil, returning: true, **options)
62+
returning
5263
end
5364

5465
def read_serialized_entries(keys)

lib/solid_cache/store/entries.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ def entry_clear
2929

3030
def entry_lock_and_write(key, &block)
3131
writing_key(key, failsafe: :increment) do
32-
Entry.lock_and_write(key, &block)
32+
Entry.lock_and_write(key) do |value|
33+
block.call(value).tap { |result| track_writes(1) if result }
34+
end
3335
end
3436
end
3537

test/unit/solid_cache_test.rb

+11
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ class SolidCacheTest < ActiveSupport::TestCase
5454
cache = lookup_store(max_age: 7200)
5555
assert_equal 7200, cache.max_age
5656
end
57+
58+
def test_write_with_unless_exist
59+
assert_equal true, @cache.write("foo", 1)
60+
assert_equal false, @cache.write("foo", 1, unless_exist: true)
61+
end
62+
63+
def test_write_expired_value_with_unless_exist
64+
assert_equal true, @cache.write(1, "aaaa", expires_in: 1.second)
65+
travel 2.seconds
66+
assert_equal true, @cache.write(1, "bbbb", expires_in: 1.second, unless_exist: true)
67+
end
5768
end
5869

5970
class SolidCacheFailsafeTest < ActiveSupport::TestCase

0 commit comments

Comments
 (0)