diff --git a/lib/faraday/http_cache.rb b/lib/faraday/http_cache.rb index f9b613e..661457e 100644 --- a/lib/faraday/http_cache.rb +++ b/lib/faraday/http_cache.rb @@ -85,6 +85,8 @@ class HttpCache < Faraday::Middleware # :instrumenter - An instrumentation object that should respond to 'instrument'. # :instrument_name - The String name of the instrument being reported on (optional). # :logger - A logger object. + # :max_entries - The maximum number of entries to store per cache key. This option is only + # used when using the +ByUrl+ cache strategy. # # Examples: # diff --git a/lib/faraday/http_cache/strategies/by_url.rb b/lib/faraday/http_cache/strategies/by_url.rb index fad9090..cdd828c 100644 --- a/lib/faraday/http_cache/strategies/by_url.rb +++ b/lib/faraday/http_cache/strategies/by_url.rb @@ -10,6 +10,11 @@ module Strategies # The original strategy by Faraday::HttpCache. # Uses URL + HTTP method to generate cache keys. class ByUrl < BaseStrategy + def initialize(options = {}) + super + @max_entries = options[:max_entries] + end + # Store a response inside the cache. # # @param [Faraday::HttpCache::Request] request - instance of the executed HTTP request. @@ -26,6 +31,7 @@ def write(request, response) end entries << entry + entries = entries.last(@max_entries) unless @max_entries.nil? cache.write(key, entries) rescue ::Encoding::UndefinedConversionError => e diff --git a/spec/strategies/by_url_spec.rb b/spec/strategies/by_url_spec.rb index a053d52..e8fdbe9 100644 --- a/spec/strategies/by_url_spec.rb +++ b/spec/strategies/by_url_spec.rb @@ -29,6 +29,29 @@ described_class.new(store: wrong) }.to raise_error(ArgumentError) end + + context 'with max_entries set' do + let(:max_entries) { 2 } + let(:strategy) { described_class.new(store: cache, max_entries: max_entries) } + let(:response) { double(serializable_hash: { response_headers: { 'Vary' => 'X-Foo' } }) } + + it 'limits the number of cached entries' do + requests = Array.new(max_entries + 1) do |i| + env = { method: :get, url: 'http://test/index', headers: { 'X-Foo' => i } } + double(env.merge(serializable_hash: env)) + end + + requests.each { |request| subject.write(request, response) } + + expect(subject.cache.read(cache_key).count).to eq(max_entries) + + expect(subject.read(requests.first)).to eq(nil) + + requests.last(max_entries).each do |request| + expect(subject.read(request)).not_to be_nil + end + end + end end describe 'storing responses' do