-
Notifications
You must be signed in to change notification settings - Fork 24
/
cache.rb
48 lines (45 loc) · 1.47 KB
/
cache.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
module Garner
module Cache
class NilBinding < StandardError; end
# Fetch a result from cache.
#
# @param bindings [Array] Objects to which the the cache result should be
# bound. These objects' keys are injected into the compound cache key.
# @param key_hash [Hash] Hash to comprise the compound cache key.
# @param options_hash [Hash] Options to be passed to Garner.config.cache.
def self.fetch(bindings, key_hash, options_hash, &_block)
if (compound_key = compound_key(bindings, key_hash))
result = Garner.config.cache.fetch(compound_key, options_hash) do
yield
end
Garner.config.cache.delete(compound_key) unless result
else
result = yield
end
result
end
def self.compound_key(bindings, key_hash)
binding_keys = bindings.map { |binding| key_for(binding) }.compact
if binding_keys.size == bindings.size
# All bindings have non-nil cache keys, proceed.
{
binding_keys: binding_keys,
context_keys: key_hash
}
else
# A nil cache key was generated. Skip caching.
# TODO: Replace this ill-documented "nil to skip" behavior
# with exceptions on inability to generate a cache key.
nil
end
end
def self.key_for(binding)
if binding.nil?
return nil unless Garner.config.whiny_nils?
fail NilBinding
else
binding.garner_cache_key
end
end
end
end