Skip to content

Commit

Permalink
Merge pull request #247 from jrafanie/cache_invalidation_is_harder
Browse files Browse the repository at this point in the history
Only return the cached value if it exists.
  • Loading branch information
Fryguy authored Jul 21, 2017
2 parents f571790 + 59aab09 commit 6bdd644
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
5 changes: 3 additions & 2 deletions lib/gems/pending/util/extensions/miq-module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ def cache_with_timeout(method, timeout = nil, &block)

old_timeout = cache[:timeout]
cache.clear if force_reload || (old_timeout && Time.now.utc > old_timeout)
break cache[:value] unless cache.empty?
break cache[:value] if cache.key?(:value)

new_timeout = timeout || 300 # 5 minutes
new_timeout = new_timeout.call if new_timeout.kind_of?(Proc)
new_timeout = Time.now.utc + new_timeout
new_value = block.call

cache[:timeout] = new_timeout
cache[:value] = block.call
cache[:value] = new_value
end
end

Expand Down
27 changes: 27 additions & 0 deletions spec/util/extensions/miq-module_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,33 @@
expect(test_module.default).to eq(value)
end

it 'clears the cache even if the block raises an exception' do
test_class.define_singleton_method(:call_count) { @call_count ||= 0 }
test_class.define_singleton_method(:call_count=) { |val| @call_count = val }
test_class.cache_with_timeout(:flapping_method) do
begin
if test_class.call_count.even?
test_class.call_count
else
raise "OOPS"
end
ensure
test_class.call_count += 1
end
end

expect(test_class.flapping_method(true)).to eq(0) # initializes cache to 0
expect(test_class.flapping_method).to eq(0) # returns from cache

test_class.flapping_method(true) rescue nil # blows up, clears cache for next request
expect(test_class.flapping_method).to eq(2) # sets new value since cache is cleared
expect(test_class.flapping_method).to eq(2) # returns from cache

test_class.flapping_method(true) rescue nil # blows up, clears cache for next request
expect(test_class.flapping_method).to eq(4) # sets new value since cache is cleared
expect(test_class.flapping_method).to eq(4) # returns from cache
end

it 'will not return the cached value when passed force_reload = true' do
value = test_class.default(true)
expect(test_class.default(true)).not_to eq(value)
Expand Down

0 comments on commit 6bdd644

Please sign in to comment.