/
adapter.rb
94 lines (79 loc) 路 2.24 KB
/
adapter.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
49
50
51
52
53
54
55
56
57
58
59
60
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
89
90
91
92
93
94
module Flipper
# Adapter wrapper that wraps vanilla adapter instances with local caching.
#
# So what is this local cache crap?
#
# The main goal of the local cache is to prevent multiple queries to an
# adapter for the same key for a given amount of time (per request, per
# background job, etc.).
#
# To facilitate with this, there is an included local cache middleware
# that enables local caching for the length of a web request. The local
# cache is enabled and cleared before each request and cleared and reset
# to original value after each request.
#
# Examples
#
# To see an example adapter that this would wrap, checkout the [memory
# adapter included with flipper](https://github.com/jnunemaker/flipper/blob/master/lib/flipper/adapters/memory.rb).
class Adapter
def self.wrap(object)
if object.is_a?(Flipper::Adapter)
object
else
new(object)
end
end
attr_reader :adapter, :use_local_cache
def initialize(adapter)
@adapter = adapter
end
def use_local_cache=(value)
local_cache.clear
@use_local_cache = value
end
def local_cache
@local_cache ||= {}
end
def using_local_cache?
@use_local_cache == true
end
def read(key)
if using_local_cache?
cache(key) { @adapter.read(key) }
else
@adapter.read(key)
end
end
def write(key, value)
@adapter.write(key, value).tap { expire_local_cache(key) }
end
def delete(key)
@adapter.delete(key).tap { expire_local_cache(key) }
end
def set_members(key)
if using_local_cache?
cache(key) { @adapter.set_members(key) }
else
@adapter.set_members(key)
end
end
def set_add(key, value)
@adapter.set_add(key, value).tap { expire_local_cache(key) }
end
def set_delete(key, value)
@adapter.set_delete(key, value).tap { expire_local_cache(key) }
end
def eql?(other)
self.class.eql?(other.class) && adapter == other.adapter
end
alias :== :eql?
private
def cache(key)
local_cache.fetch(key) { local_cache[key] = yield }
end
def expire_local_cache(key)
local_cache.delete(key) if using_local_cache?
end
end
end