diff --git a/lib/solid_cache/store/api.rb b/lib/solid_cache/store/api.rb index b7859ab..ecd6c62 100644 --- a/lib/solid_cache/store/api.rb +++ b/lib/solid_cache/store/api.rb @@ -53,12 +53,8 @@ def write_entry(key, entry, raw: false, unless_exist: false, **options) payload = serialize_entry(entry, raw: raw, **options) if unless_exist - written = false - entry_lock_and_write(key) do |value| - if value.nil? || deserialize_entry(value, **options).expired? - written = true - payload - end + written = !!entry_lock_and_write(key) do |value| + payload if value.nil? || deserialize_entry(value, **options).expired? end else written = entry_write(key, payload) diff --git a/test/unit/solid_cache_test.rb b/test/unit/solid_cache_test.rb index 2376345..adec85b 100644 --- a/test/unit/solid_cache_test.rb +++ b/test/unit/solid_cache_test.rb @@ -81,6 +81,23 @@ class SolidCacheFailsafeTest < ActiveSupport::TestCase @peek = lookup_store(expires_in: 60) end + test "write with unless_exist returns false when persistence fails" do + SolidCache::Entry.expects(:write).raises(ActiveRecord::Deadlocked) + + assert_equal false, @cache.write("foo", "bar", unless_exist: true) + assert_nil @cache.read("foo") + end + + test "failed write with unless_exist does not populate the local cache" do + SolidCache::Entry.expects(:write).raises(ActiveRecord::StatementTimeout) + + @cache.with_local_cache do + @cache.write("foo", "bar", unless_exist: true) + + assert_nil @cache.read("foo") + end + end + def emulating_unavailability wait_for_background_tasks(@cache) emulating_timeouts do