From eb1cf396c52661307b26139691e4e9251ff0e124 Mon Sep 17 00:00:00 2001 From: Alexey Zapparov Date: Mon, 3 Jul 2023 15:05:09 +0200 Subject: [PATCH] feat: Provide better Rails cache store support Current implementation disrespects expiration TTL, polluting redis with non-expirable keys. Proposed solution wraps Rails.cache (configured with :redis_cache_store) with adapter that respects Rails cache semantics. --- lib/geocoder/cache.rb | 2 +- .../active_support/cache/redis_cache_store.rb | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 lib/geocoder/cache_stores/active_support/cache/redis_cache_store.rb diff --git a/lib/geocoder/cache.rb b/lib/geocoder/cache.rb index 9921783d5..c42918dd2 100644 --- a/lib/geocoder/cache.rb +++ b/lib/geocoder/cache.rb @@ -1,4 +1,4 @@ -Dir["#{__dir__}/cache_stores/*.rb"].each {|file| require file } +Dir["#{__dir__}/cache_stores/**/*.rb"].each {|file| require file } module Geocoder class Cache diff --git a/lib/geocoder/cache_stores/active_support/cache/redis_cache_store.rb b/lib/geocoder/cache_stores/active_support/cache/redis_cache_store.rb new file mode 100644 index 000000000..454c92538 --- /dev/null +++ b/lib/geocoder/cache_stores/active_support/cache/redis_cache_store.rb @@ -0,0 +1,37 @@ +require 'geocoder/cache_stores/base' + +module Geocoder::CacheStore::ActiveSupport::Cache + class RedisCacheStore < Geocoder::CacheStore::Base + def write(url, value, expires_in = @config[:expiration]) + if expires_in.present? + store.write(key_for(url), value, expires_in: expires_in) + else + store.write(key_for(url), value) + end + end + + def read(url) + store.read(key_for(url)) + end + + def keys + if store.redis.respond_to?(:with) + store.redis.with do |redis| + redis.scan_each(match: "#{prefix}*").to_a.uniq + end + else + store.redis.scan_each(match: "#{prefix}*").to_a.uniq + end + end + + def urls + return keys if prefix.blank? + + keys.map { |key| key.delete_prefix(prefix) } + end + + def expire_single_url(url) + store.delete(key_for(url)) + end + end +end