Skip to content

Commit

Permalink
[ISSUE-71] Serialize payload responses for cache value, optionally ha…
Browse files Browse the repository at this point in the history
…sh keys
  • Loading branch information
jlurena committed Oct 15, 2024
1 parent 63e43f3 commit 48c4f44
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 7 deletions.
3 changes: 2 additions & 1 deletion lib/cached_resource.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "msgpack"
require "nilio"
require "ostruct"

require "nilio"
require "active_support/cache"
require "active_support/concern"
require "active_support/logger"
Expand Down
11 changes: 8 additions & 3 deletions lib/cached_resource/caching.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def is_any_collection?(*arguments)
# Read a entry from the cache for the given key.
def cache_read(key)
object = cached_resource.cache.read(key).try do |json_cache|
json = ActiveSupport::JSON.decode(json_cache)
json = ActiveSupport::JSON.decode(MessagePack.unpack(json_cache))

unless json.nil?
cache = json_to_object(json)
Expand All @@ -130,7 +130,8 @@ def cache_write(key, object, *arguments)
params = options[:params]
prefix_options, query_options = split_options(params)

result = cached_resource.cache.write(key, object_to_json(object, prefix_options, query_options), race_condition_ttl: cached_resource.race_condition_ttl, expires_in: cached_resource.generate_ttl)
serialized_json = MessagePack.pack(object_to_json(object, prefix_options, query_options))
result = cached_resource.cache.write(key, serialized_json, race_condition_ttl: cached_resource.race_condition_ttl, expires_in: cached_resource.generate_ttl)
result && cached_resource.logger.info("#{CachedResource::Configuration::LOGGER_PREFIX} WRITE #{key}")
result
end
Expand Down Expand Up @@ -158,7 +159,11 @@ def cache_key_delete_pattern

# Generate the request cache key.
def cache_key(*arguments)
"#{name_key}/#{arguments.join("/")}".downcase.delete(" ")
key = "#{name_key}/#{arguments.join("/")}".downcase.delete(" ")
if cached_resource.max_key_length && key.length > cached_resource.max_key_length
key = Digest::SHA256.hexdigest(key)
end
key
end

def name_key
Expand Down
8 changes: 6 additions & 2 deletions lib/cached_resource/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class Configuration < OpenStruct
# prefix for log messages
LOGGER_PREFIX = "[cached_resource]"

# Max key length
MAX_KEY_LENGTH = nil

# Initialize a Configuration with the given options, overriding any
# defaults. The following options exist for cached resource:
# :enabled, default: true
Expand All @@ -32,10 +35,11 @@ def initialize(options = {})
collection_synchronize: false,
enabled: true,
logger: defined?(Rails.logger) && Rails.logger || LOGGER,
max_key_length: options.fetch(:max_key_length, MAX_KEY_LENGTH),
race_condition_ttl: 86400,
ttl: 604800,
ttl_randomization_scale: 1..2,
ttl_randomization: false,
ttl_randomization_scale: 1..2
ttl: 604800
}.merge(options))
end

Expand Down
2 changes: 1 addition & 1 deletion lib/cached_resource/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module CachedResource
VERSION = "9.0.0"
VERSION = "9.1.0"
end
22 changes: 22 additions & 0 deletions spec/cached_resource/caching_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def read_from_cache(key, model = Thing)
enabled: true,
generate_ttl: 604800,
logger: double(:thing_logger, info: nil, error: nil),
max_key_length: nil,
race_condition_ttl: 86400,
ttl_randomization_scale: 1..2,
ttl_randomization: false,
Expand All @@ -58,6 +59,7 @@ def read_from_cache(key, model = Thing)
enabled: true,
generate_ttl: 604800,
logger: double(:not_the_thing_logger, info: nil, error: nil),
max_key_length: nil,
race_condition_ttl: 86400,
ttl_randomization_scale: 1..2,
ttl_randomization: false,
Expand Down Expand Up @@ -88,6 +90,26 @@ def read_from_cache(key, model = Thing)
allow(not_the_thing_cached_resource).to receive(:enabled).and_return(true)
end

context "When a `max_key_length` is set" do
before do
allow(thing_cached_resource).to receive(:max_key_length).and_return(10)
end

context "When key length is greater than `max_key_length`" do
it "caches a response with hashed key" do
result = Thing.find(1, from: "path", params: {foo: "bar"})
expect(read_from_cache(Digest::SHA256.hexdigest('thing/1/{:from=>"path",:params=>{:foo=>"bar"}}'))).to eq(result)
end
end

context "When key length is less than `max_key_length`" do
it "caches a response with unhashed key" do
result = Thing.find(1)
expect(read_from_cache("thing/1")).to eq(result)
end
end
end

context "Caching single resource" do
it "caches a response" do
result = Thing.find(1)
Expand Down
4 changes: 4 additions & 0 deletions spec/cached_resource/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class Bar3 < Bar
expect(configuration.ttl).to eq(604800)
end

it "should have key length of Configuration::MAX_KEY_LENGTH" do
expect(configuration.max_key_length).to eq(Configuration::MAX_KEY_LENGTH)
end

it "should disable collection synchronization" do
expect(configuration.collection_synchronize).to eq(false)
end
Expand Down

0 comments on commit 48c4f44

Please sign in to comment.