Class: IdentityCache::MemoizedCacheProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/identity_cache/memoized_cache_proxy.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cache_adaptor = nil) ⇒ MemoizedCacheProxy

Returns a new instance of MemoizedCacheProxy.


8
9
10
11
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 8

def initialize(cache_adaptor = nil)
  self.cache_backend = cache_adaptor || Rails.cache
  @key_value_maps = Hash.new {|h, k| h[k] = {} }
end

Instance Attribute Details

#cache_fetcherObject (readonly)

Returns the value of attribute cache_fetcher


6
7
8
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 6

def cache_fetcher
  @cache_fetcher
end

Instance Method Details

#cache_backend=(cache_adaptor) ⇒ Object


13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 13

def cache_backend=(cache_adaptor)
  if cache_adaptor.respond_to?(:cas) && cache_adaptor.respond_to?(:cas_multi)
    @cache_fetcher = CacheFetcher.new(cache_adaptor)
  else
    case cache_adaptor
    when ActiveSupport::Cache::MemoryStore, ActiveSupport::Cache::NullStore
      # no need for CAS support
    else
      warn "[IdentityCache] Missing CAS support in cache backend #{cache_adaptor.class} "\
           "which is needed for cache consistency"
    end
    @cache_fetcher = FallbackFetcher.new(cache_adaptor)
  end
end

#clearObject


117
118
119
120
121
122
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 117

def clear
  ActiveSupport::Notifications.instrument('cache_clear.identity_cache') do
    clear_memoization
    @cache_fetcher.clear
  end
end

#delete(key) ⇒ Object


48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 48

def delete(key)
  memoizing = memoizing?
  ActiveSupport::Notifications.instrument('cache_delete.identity_cache', memoizing: memoizing) do
    memoized_key_values.delete(key) if memoizing
    if result = @cache_fetcher.delete(key)
      IdentityCache.logger.debug {"[IdentityCache] delete recorded for #{key}"}
    else
      IdentityCache.logger.error {"[IdentityCache] delete failed for #{key}"}
    end
    result
  end
end

#fetch(key) ⇒ Object


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 61

def fetch(key)
  memo_misses = 0
  cache_misses = 0

  value = ActiveSupport::Notifications.instrument('cache_fetch.identity_cache') do |payload|
    payload[:resolve_miss_time] = 0.0

    value = fetch_memoized(key) do
      memo_misses = 1
      @cache_fetcher.fetch(key) do
        cache_misses = 1
        instrument_duration(payload, :resolve_miss_time) do
          yield
        end
      end
    end
    set_instrumentation_payload(payload, num_keys: 1, memo_misses: memo_misses, cache_misses: cache_misses)
    value
  end

  if cache_misses > 0
    IdentityCache.logger.debug { "[IdentityCache] cache miss for #{key}" }
  else
    IdentityCache.logger.debug { "[IdentityCache] #{ memo_misses > 0 ? '(cache_backend)' : '(memoized)' } cache hit for #{key}" }
  end

  value
end

#fetch_multi(*keys) ⇒ Object


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 90

def fetch_multi(*keys)
  memo_miss_keys = EMPTY_ARRAY
  cache_miss_keys = EMPTY_ARRAY

  result = ActiveSupport::Notifications.instrument('cache_fetch_multi.identity_cache') do |payload|
    payload[:resolve_miss_time] = 0.0

    result = fetch_multi_memoized(keys) do |non_memoized_keys|
      memo_miss_keys = non_memoized_keys
      @cache_fetcher.fetch_multi(non_memoized_keys) do |missing_keys|
        cache_miss_keys = missing_keys
        instrument_duration(payload, :resolve_miss_time) do
          yield missing_keys
        end
      end
    end

    set_instrumentation_payload(payload, num_keys: keys.length,
      memo_misses: memo_miss_keys.length, cache_misses: cache_miss_keys.length)
    result
  end

  log_multi_result(keys, memo_miss_keys, cache_miss_keys)

  result
end

#memoized_key_valuesObject


28
29
30
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 28

def memoized_key_values
  @key_value_maps[Thread.current]
end

#with_memoization(&block) ⇒ Object


32
33
34
35
36
37
38
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 32

def with_memoization(&block)
  Thread.current[:memoizing_idc] = true
  yield
ensure
  clear_memoization
  Thread.current[:memoizing_idc] = false
end

#write(key, value) ⇒ Object


40
41
42
43
44
45
46
# File 'lib/identity_cache/memoized_cache_proxy.rb', line 40

def write(key, value)
  memoizing = memoizing?
  ActiveSupport::Notifications.instrument('cache_write.identity_cache', memoizing: memoizing) do
    memoized_key_values[key] = value if memoizing
    @cache_fetcher.write(key, value)
  end
end