Skip to content

Commit

Permalink
Fix AS::Cache 7.1 format to properly compress bare strings
Browse files Browse the repository at this point in the history
The bare string and compression features weren't working properly
together.

I discovered this while trying to fix deprecation warnings.
  • Loading branch information
byroot committed Jul 5, 2023
1 parent 76deaf6 commit cf67782
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
19 changes: 15 additions & 4 deletions activesupport/lib/active_support/cache/serializer_with_fallback.rb
Expand Up @@ -159,12 +159,20 @@ module Marshal71WithFallback
MARK_UNCOMPRESSED = "\x00".b.freeze
MARK_COMPRESSED = "\x01".b.freeze

def dump(entry, raw = false)
if raw
super(entry)
else
MARK_UNCOMPRESSED + super(entry)
end
end

def _dump(entry)
MARK_UNCOMPRESSED + Marshal.dump(entry.pack)
Marshal.dump(entry.pack)
end

def dump_compressed(entry, threshold)
dumped = Marshal.dump(entry.pack)
dumped = dump(entry, true)
if compressed = try_compress(dumped, threshold)
MARK_COMPRESSED + compressed
else
Expand All @@ -175,7 +183,7 @@ def dump_compressed(entry, threshold)
def _load(marked)
dumped = marked.byteslice(1..-1)
dumped = decompress(dumped) if marked.start_with?(MARK_COMPRESSED)
Cache::Entry.unpack(Marshal.load(dumped))
try_load_bare_string(dumped) || Cache::Entry.unpack(Marshal.load(dumped))
end

def dumped?(dumped)
Expand All @@ -186,7 +194,10 @@ def dumped?(dumped)
module Marshal70WithFallback
include Marshal71WithFallback
extend self
alias :dump :_dump # Prevent dumping bare strings.

def try_dump_bare_string(_entry)
nil # Prevent dumping bare strings.
end
end

module MessagePackWithFallback
Expand Down
2 changes: 2 additions & 0 deletions activesupport/test/abstract_unit.rb
Expand Up @@ -29,6 +29,8 @@
ActiveSupport.to_time_preserves_timezone = ENV.fetch("PRESERVE_TIMEZONES", "1") == "1"
end

ActiveSupport::Cache.format_version = 7.1

# Disable available locale checks to avoid warnings running the test suite.
I18n.enforce_available_locales = false

Expand Down
Expand Up @@ -10,7 +10,7 @@ module CacheStoreFormatVersionBehavior
included do
test "format version affects default coder" do
coders = FORMAT_VERSIONS.map do |format_version|
ActiveSupport::Cache.with(format_version: format_version) do
with_format(format_version) do
lookup_store.instance_variable_get(:@coder)
end
end
Expand All @@ -19,7 +19,7 @@ module CacheStoreFormatVersionBehavior
end

test "invalid format version raises" do
ActiveSupport::Cache.with(format_version: 0) do
with_format(0) do
assert_raises do
lookup_store
end
Expand All @@ -30,26 +30,33 @@ module CacheStoreFormatVersionBehavior
test "format version #{read_version.inspect} can read #{write_version.inspect} entries" do
key = SecureRandom.uuid

ActiveSupport::Cache.with(format_version: write_version) do
with_format(write_version) do
lookup_store.write(key, "value for #{key}")
end

ActiveSupport::Cache.with(format_version: read_version) do
with_format(read_version) do
assert_equal "value for #{key}", lookup_store.read(key)
end
end

test "format version #{read_version.inspect} can read #{write_version.inspect} entries with compression" do
key = SecureRandom.uuid

ActiveSupport::Cache.with(format_version: write_version) do
with_format(write_version) do
lookup_store(compress_threshold: 1).write(key, key * 10)
end

ActiveSupport::Cache.with(format_version: read_version) do
with_format(read_version) do
assert_equal key * 10, lookup_store.read(key)
end
end
end
end

private
def with_format(format_version, &block)
ActiveSupport.deprecator.silence do
ActiveSupport::Cache.with(format_version: format_version, &block)
end
end
end

0 comments on commit cf67782

Please sign in to comment.