double_write_cache_stores 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -2
- data/double_write_cache_stores.gemspec +3 -2
- data/lib/double_write_cache_stores/client.rb +22 -36
- data/lib/double_write_cache_stores/version.rb +1 -1
- data/spec/double_write_cache_stores/client_spec.rb +67 -62
- data/spec/spec_helper.rb +1 -0
- metadata +36 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dbec8739b2952e40813ae8355317815e4ac6769
|
4
|
+
data.tar.gz: 7f17258222ba0e1211ee777e69193def91723fc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c84a1e5255940a10299a068298666a82138f99e9623d737256f20f572bc6f792be8bc90ea5a93ac2fc8eef76ed0b1e1fdfd778fb865e08e3d1d186b1ef6d3c8
|
7
|
+
data.tar.gz: bc644b50386794570dc390a7e40af9bc4a86e6bb1f527df621a7da213f89bb8d6936714f2deecf1c423b42d9b58c242c58de9dabb64e8d06f295e810ed908fd0
|
data/README.md
CHANGED
@@ -2,10 +2,16 @@
|
|
2
2
|
|
3
3
|
pre-warning(double write to cach store and other cache store) cache store wrapper. will switch cache store.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Convertible interface, get/set by cache store
|
6
6
|
|
7
|
+
- Padrino::Cache(moneta)
|
7
8
|
- ActiveSupport::Cache::DalliStore(Dalli)
|
8
|
-
- Padrino::Cache
|
9
|
+
- Padrino::Cache::Store::Memcache
|
10
|
+
|
11
|
+
## Support backend cache store
|
12
|
+
|
13
|
+
- ActiveSupport::Cache::DalliStore(Dalli)
|
14
|
+
- Padrino::Cache::Store::Memcache
|
9
15
|
|
10
16
|
## Installation
|
11
17
|
|
@@ -22,7 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec"
|
24
24
|
spec.add_development_dependency "activesupport", "= 3.2.15"
|
25
|
-
spec.add_development_dependency "dalli", "= 2.
|
25
|
+
spec.add_development_dependency "dalli", "= 2.7.0"
|
26
26
|
spec.add_development_dependency "pry"
|
27
|
-
spec.add_development_dependency "padrino", "0.
|
27
|
+
spec.add_development_dependency "padrino", "0.10.7"
|
28
|
+
spec.add_development_dependency "tilt", "1.3.7"
|
28
29
|
end
|
@@ -17,6 +17,20 @@ class DoubleWriteCacheStores::Client
|
|
17
17
|
get_or_read_method_call key
|
18
18
|
end
|
19
19
|
|
20
|
+
def get_cas(key)
|
21
|
+
@read_and_write_store.get_cas key
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_cas(key, value, cas, options = nil)
|
25
|
+
cas_unique = @read_and_write_store.set_cas key, value, cas, options
|
26
|
+
|
27
|
+
if @write_only_store && cas_unique
|
28
|
+
set_or_write_method_call @write_only_store, key, value, options
|
29
|
+
end
|
30
|
+
|
31
|
+
cas_unique
|
32
|
+
end
|
33
|
+
|
20
34
|
def read(key)
|
21
35
|
get_or_read_method_call key
|
22
36
|
end
|
@@ -27,11 +41,7 @@ class DoubleWriteCacheStores::Client
|
|
27
41
|
end
|
28
42
|
|
29
43
|
def []=(key, value)
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
def store(key, value, options = nil)
|
34
|
-
write_cache_store key, value, options
|
44
|
+
set key, value
|
35
45
|
end
|
36
46
|
|
37
47
|
def set(key, value, options = nil)
|
@@ -44,9 +54,7 @@ class DoubleWriteCacheStores::Client
|
|
44
54
|
|
45
55
|
def touch(key)
|
46
56
|
result = false
|
47
|
-
|
48
|
-
read_and_write_backend = get_backend @read_and_write_store
|
49
|
-
|
57
|
+
read_and_write_backend = @read_and_write_store.instance_variable_get('@backend') || @read_and_write_store.instance_variable_get('@data')
|
50
58
|
if read_and_write_backend && read_and_write_backend.respond_to?(:touch)
|
51
59
|
result = read_and_write_backend.touch key
|
52
60
|
write_only_store_touch key
|
@@ -55,43 +63,22 @@ class DoubleWriteCacheStores::Client
|
|
55
63
|
end
|
56
64
|
|
57
65
|
def flush
|
58
|
-
if flush_cache_store || flush_cache_store(:
|
66
|
+
if flush_cache_store || flush_cache_store(:clear)
|
59
67
|
true
|
60
68
|
else
|
61
69
|
false
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
65
|
-
alias :clear :flush
|
66
|
-
|
67
73
|
private
|
68
74
|
|
69
|
-
def get_backend cache_store
|
70
|
-
if cache_store.is_a? Padrino::Cache::LegacyStore
|
71
|
-
cache_store.instance_variable_get('@adapter').instance_variable_get('@adapter').instance_variable_get('@backend')
|
72
|
-
else
|
73
|
-
cache_store.instance_variable_get '@backend'
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
75
|
def write_cache_store(key, value, options = nil)
|
78
76
|
set_or_write_method_call @read_and_write_store, key, value, options
|
79
77
|
set_or_write_method_call @write_only_store, key, value, options if @write_only_store
|
80
78
|
end
|
81
79
|
|
82
80
|
def set_or_write_method_call cache_store, key, value, options
|
83
|
-
if cache_store.
|
84
|
-
if options && options[:expires_in]
|
85
|
-
options[:expires] = options[:expires_in].to_i
|
86
|
-
options[:expires_in] = nil
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
if cache_store.respond_to?(:[]=) && options.nil?
|
91
|
-
cache_store[key] = value
|
92
|
-
elsif cache_store.respond_to? :store
|
93
|
-
cache_store.store key, value, options
|
94
|
-
elsif cache_store.respond_to? :set
|
81
|
+
if cache_store.respond_to? :set
|
95
82
|
cache_store.set key, value, options
|
96
83
|
elsif cache_store.respond_to? :write
|
97
84
|
cache_store.write key, value, options
|
@@ -99,16 +86,14 @@ class DoubleWriteCacheStores::Client
|
|
99
86
|
end
|
100
87
|
|
101
88
|
def get_or_read_method_call key
|
102
|
-
if @read_and_write_store.respond_to? :
|
103
|
-
@read_and_write_store[key]
|
104
|
-
elsif @read_and_write_store.respond_to? :get
|
89
|
+
if @read_and_write_store.respond_to? :get
|
105
90
|
@read_and_write_store.get key
|
106
91
|
elsif @read_and_write_store.respond_to? :read
|
107
92
|
@read_and_write_store.read key
|
108
93
|
end
|
109
94
|
end
|
110
95
|
|
111
|
-
def flush_cache_store(method = :
|
96
|
+
def flush_cache_store(method = :flush)
|
112
97
|
if @read_and_write_store.respond_to? method
|
113
98
|
if @write_only_store && @write_only_store.respond_to?(method)
|
114
99
|
@write_only_store.send method
|
@@ -121,7 +106,8 @@ class DoubleWriteCacheStores::Client
|
|
121
106
|
|
122
107
|
def write_only_store_touch(key)
|
123
108
|
if @write_only_store
|
124
|
-
|
109
|
+
write_only_backend = @write_only_store.instance_variable_get('@backend') || @write_only_store.instance_variable_get('@data')
|
110
|
+
if write_only_backend
|
125
111
|
write_only_backend.touch key if write_only_backend.respond_to?(:touch)
|
126
112
|
end
|
127
113
|
end
|
@@ -29,13 +29,10 @@ describe DoubleWriteCacheStores::Client do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
describe '#[]=' do
|
33
|
-
|
32
|
+
describe 'set #[]=(key, value) and get #[](key)' do
|
33
|
+
it 'set value and get value' do
|
34
34
|
copy_cache_store['key'] = 'example-value'
|
35
|
-
|
36
|
-
it 'set value to multi store' do
|
37
|
-
expect(read_and_write_store.read 'key').to eq 'example-value'
|
38
|
-
expect(write_only_store.read 'key').to eq 'example-value'
|
35
|
+
expect(copy_cache_store['key']).to eq 'example-value'
|
39
36
|
end
|
40
37
|
end
|
41
38
|
|
@@ -59,10 +56,10 @@ describe DoubleWriteCacheStores::Client do
|
|
59
56
|
{ :namespace => "app_v1", :compress => true }
|
60
57
|
end
|
61
58
|
let :support_touch_read_and_write_store do
|
62
|
-
Padrino::Cache.new(
|
59
|
+
Padrino::Cache::Store::Memcache.new(::Dalli::Client.new('localhost:11211', options))
|
63
60
|
end
|
64
61
|
let :support_touch_write_only_store do
|
65
|
-
Padrino::Cache.new(
|
62
|
+
Padrino::Cache::Store::Memcache.new(::Dalli::Client.new('localhost:21211', options))
|
66
63
|
end
|
67
64
|
let :support_touch_copy_cache_store do
|
68
65
|
DoubleWriteCacheStores::Client.new support_touch_read_and_write_store, support_touch_write_only_store
|
@@ -70,30 +67,26 @@ describe DoubleWriteCacheStores::Client do
|
|
70
67
|
before do
|
71
68
|
support_touch_copy_cache_store.set 'touch-key', 'touch-value', :expires_in => 1.day
|
72
69
|
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
before do
|
79
|
-
copy_cache_store.write 'unsupport-touch-key', 'touch-value', :expires_in => 1.day
|
80
|
-
end
|
81
|
-
it 'not doing touch' do
|
82
|
-
expect(copy_cache_store.touch 'unsupport-touch-key').to be_false
|
70
|
+
|
71
|
+
context 'Dalli::Client' do
|
72
|
+
it 'example' do
|
73
|
+
expect(support_touch_copy_cache_store.touch 'touch-key').to be true
|
74
|
+
expect(support_touch_copy_cache_store.touch 'non-set-key').to be nil
|
83
75
|
end
|
84
76
|
end
|
85
|
-
end
|
86
77
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
copy_cache_store.write 'key', 'example-read-value', :expires_in => 1.day
|
78
|
+
context 'ActiveSupport::Cache::DalliStore' do
|
79
|
+
let :double_write_dalli_store do
|
80
|
+
DoubleWriteCacheStores::Client.new ActiveSupport::Cache::DalliStore.new('localhost:11211', options), ActiveSupport::Cache::DalliStore.new('localhost:21211', options)
|
91
81
|
end
|
92
|
-
|
93
|
-
|
82
|
+
|
83
|
+
before do
|
84
|
+
double_write_dalli_store.set 'touch-key', 'touch-valule', :expires_in => 1.day
|
94
85
|
end
|
95
|
-
|
96
|
-
|
86
|
+
|
87
|
+
it 'example' do
|
88
|
+
expect(double_write_dalli_store.touch 'touch-key').to be true
|
89
|
+
expect(double_write_dalli_store.touch 'non-set-key').to be nil
|
97
90
|
end
|
98
91
|
end
|
99
92
|
end
|
@@ -139,10 +132,10 @@ describe DoubleWriteCacheStores::Client do
|
|
139
132
|
{ :namespace => "app_v1", :compress => true }
|
140
133
|
end
|
141
134
|
let :support_flash_read_and_write_store do
|
142
|
-
Padrino::Cache.new(
|
135
|
+
Padrino::Cache::Store::Memcache.new(::Dalli::Client.new('localhost:11211', options))
|
143
136
|
end
|
144
137
|
let :support_flash_write_only_store do
|
145
|
-
Padrino::Cache.new(
|
138
|
+
Padrino::Cache::Store::Memcache.new(::Dalli::Client.new('localhost:21211', options))
|
146
139
|
end
|
147
140
|
let :support_flash_copy_cache_store do
|
148
141
|
DoubleWriteCacheStores::Client.new support_flash_read_and_write_store, support_flash_write_only_store
|
@@ -152,54 +145,66 @@ describe DoubleWriteCacheStores::Client do
|
|
152
145
|
end
|
153
146
|
it 'example' do
|
154
147
|
expect(support_flash_copy_cache_store.get 'will-flush-key').to eq 'will-flush-value'
|
155
|
-
expect(support_flash_copy_cache_store.flush).to
|
148
|
+
expect(support_flash_copy_cache_store.flush).to be true
|
156
149
|
expect(support_flash_copy_cache_store.get 'will-flush-key').to be_nil
|
157
150
|
end
|
158
151
|
end
|
159
152
|
end
|
160
153
|
|
161
|
-
describe
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
end
|
154
|
+
describe "#get_cas" do
|
155
|
+
context "when support get_cas method in backend cache store" do
|
156
|
+
let :support_get_cas_cache_store do
|
157
|
+
read_and_write = ::Dalli::Client.new(['localhost:11211'])
|
158
|
+
write_only = ::Dalli::Client.new(['localhost:21211'])
|
159
|
+
DoubleWriteCacheStores::Client.new read_and_write, write_only
|
160
|
+
end
|
170
161
|
|
171
|
-
|
172
|
-
|
173
|
-
{ :namespace => "app_v1", :compress => true }
|
162
|
+
before do
|
163
|
+
support_get_cas_cache_store.set 'cas-dalli-key', 'cas-dalli-value'
|
174
164
|
end
|
175
165
|
|
176
|
-
|
177
|
-
|
166
|
+
it 'example' do
|
167
|
+
expect(support_get_cas_cache_store.get_cas('cas-dalli-key')[0]).to eq 'cas-dalli-value'
|
168
|
+
expect(support_get_cas_cache_store.get_cas('cas-dalli-key')[1]).to be_kind_of(Integer)
|
169
|
+
end
|
178
170
|
end
|
179
171
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
172
|
+
context "when doesn't support get_cas method in backend cache store" do
|
173
|
+
let :not_support_get_cas_cache_store do
|
174
|
+
DoubleWriteCacheStores::Client.new ActiveSupport::Cache::DalliStore.new('localhost:11211'), ActiveSupport::Cache::DalliStore.new('localhost:21211')
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should raise NoMethodError' do
|
178
|
+
expect{ not_support_get_cas_cache_store.get_cas 'cas-key' }.to raise_error(NoMethodError)
|
179
|
+
end
|
184
180
|
end
|
181
|
+
end
|
185
182
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
183
|
+
describe "#set_cas" do
|
184
|
+
context "when support set_cas method in backend cache store" do
|
185
|
+
let :support_set_cas_cache_store do
|
186
|
+
read_and_write = ::Dalli::Client.new(['localhost:11211'])
|
187
|
+
write_only = ::Dalli::Client.new(['localhost:21211'])
|
188
|
+
DoubleWriteCacheStores::Client.new read_and_write, write_only
|
189
|
+
end
|
190
|
+
let :cas_unique do
|
191
|
+
support_set_cas_cache_store.set('cas-dalli-key', 'cas-value')
|
192
|
+
support_set_cas_cache_store.get_cas('cas-dalli-key')[1]
|
193
|
+
end
|
192
194
|
|
195
|
+
it 'example' do
|
196
|
+
expect(support_set_cas_cache_store.set_cas('cas-dalli-key', 'cas-dalli-value', cas_unique)).to be_kind_of(Integer)
|
197
|
+
end
|
198
|
+
end
|
193
199
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
200
|
+
context "when doesn't support set_cas method in backend cache store" do
|
201
|
+
let :not_support_set_cas_cache_store do
|
202
|
+
DoubleWriteCacheStores::Client.new ActiveSupport::Cache::DalliStore.new('localhost:11211'), ActiveSupport::Cache::DalliStore.new('localhost:21211')
|
203
|
+
end
|
198
204
|
|
199
|
-
|
200
|
-
|
201
|
-
|
205
|
+
it 'should raise NoMethodError' do
|
206
|
+
expect{ not_support_set_cas_cache_store.set_cas('cas-key', 'cas-value', 1) }.to raise_error(NoMethodError)
|
207
|
+
end
|
202
208
|
end
|
203
209
|
end
|
204
|
-
|
205
210
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: double_write_cache_stores
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hirocaster
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
@@ -72,26 +72,26 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - '='
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 2.
|
75
|
+
version: 2.7.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - '='
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.
|
82
|
+
version: 2.7.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: pry
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
@@ -100,25 +100,39 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - '='
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
103
|
+
version: 0.10.7
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - '='
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
111
|
-
|
112
|
-
|
110
|
+
version: 0.10.7
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: tilt
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.3.7
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.3.7
|
125
|
+
description: " pre-warning(double write to cach store and other cache store) cache
|
126
|
+
store wrapper. will switch cache store. "
|
113
127
|
email:
|
114
128
|
- hohtsuka@gmail.com
|
115
129
|
executables: []
|
116
130
|
extensions: []
|
117
131
|
extra_rdoc_files: []
|
118
132
|
files:
|
119
|
-
- .gitignore
|
120
|
-
- .rspec
|
121
|
-
- .travis.yml
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
122
136
|
- Gemfile
|
123
137
|
- LICENSE.txt
|
124
138
|
- README.md
|
@@ -140,17 +154,17 @@ require_paths:
|
|
140
154
|
- lib
|
141
155
|
required_ruby_version: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
|
-
- -
|
157
|
+
- - ">="
|
144
158
|
- !ruby/object:Gem::Version
|
145
159
|
version: '0'
|
146
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
161
|
requirements:
|
148
|
-
- -
|
162
|
+
- - ">="
|
149
163
|
- !ruby/object:Gem::Version
|
150
164
|
version: '0'
|
151
165
|
requirements: []
|
152
166
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.
|
167
|
+
rubygems_version: 2.2.2
|
154
168
|
signing_key:
|
155
169
|
specification_version: 4
|
156
170
|
summary: Double write cache stores wrapper.
|