memcached_store 1.2.0 → 2.3.4
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 35c62775da1377543a0a6720634ffb2a8305f9797f68f953321fe6172601c474
|
4
|
+
data.tar.gz: 1a6faa8fbc0e24c90368596627cd0811619be98bc3b752605eef244e99a489fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: edb29ef36b023d97373270005715f2c734b28779e889dd4a5c3dbf9a7147314198e719d0b296acee7426f621f8157c321c906f1095284809333ac5806e7bc492
|
7
|
+
data.tar.gz: e842f684725982fec3815f225a76edaa65c558bec03330fa016382c1acfe16b3dff4f58bde75d1105f5f7395cb438e1cbb9c42b7b5b8a1f5b07b66aa0d85db43
|
@@ -12,6 +12,16 @@ module ActiveSupport
|
|
12
12
|
class MemcachedSnappyStore < MemcachedStore
|
13
13
|
class UnsupportedOperation < StandardError; end
|
14
14
|
|
15
|
+
module SnappyCompressor
|
16
|
+
def self.compress(source)
|
17
|
+
Snappy.deflate(source)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.decompress(source)
|
21
|
+
Snappy.inflate(source)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
15
25
|
def increment(*)
|
16
26
|
raise UnsupportedOperation, "increment is not supported by: #{self.class.name}"
|
17
27
|
end
|
@@ -25,21 +35,10 @@ module ActiveSupport
|
|
25
35
|
false
|
26
36
|
end
|
27
37
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
[Snappy.deflate(value), true]
|
33
|
-
end
|
34
|
-
|
35
|
-
def deserialize_entry(compressed_value)
|
36
|
-
if compressed_value
|
37
|
-
super(Snappy.inflate(compressed_value))
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def cas_raw?(_options)
|
42
|
-
true
|
38
|
+
def initialize(*addresses, **options)
|
39
|
+
options[:codec] ||= ActiveSupport::Cache::MemcachedStore::Codec.new(compressor: SnappyCompressor)
|
40
|
+
options[:compress] = false
|
41
|
+
super(*addresses, **options)
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# file havily based out off https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/cache/mem_cache_store.rb
|
2
2
|
require 'digest/md5'
|
3
|
+
require 'delegate'
|
3
4
|
|
4
5
|
module ActiveSupport
|
5
6
|
module Cache
|
@@ -13,34 +14,90 @@ module ActiveSupport
|
|
13
14
|
class MemcachedStore < Store
|
14
15
|
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
|
15
16
|
|
17
|
+
class Codec
|
18
|
+
# use dalli compatible flags
|
19
|
+
SERIALIZED_FLAG = 0x1
|
20
|
+
COMPRESSED_FLAG = 0x2
|
21
|
+
|
22
|
+
# Older versions of this gem would use 0 for the flags whether or not
|
23
|
+
# the value was marshal dumped. By setting this flag, we can tell if
|
24
|
+
# it were set with an older version for backwards compatible decoding.
|
25
|
+
RAW_FLAG = 0x10
|
26
|
+
|
27
|
+
def initialize(serializer: Marshal, compressor: nil)
|
28
|
+
@serializer = serializer
|
29
|
+
@compressor = compressor
|
30
|
+
end
|
31
|
+
|
32
|
+
def encode(_key, value, flags)
|
33
|
+
unless value.is_a?(String)
|
34
|
+
flags |= SERIALIZED_FLAG
|
35
|
+
value = @serializer.dump(value)
|
36
|
+
end
|
37
|
+
if @compressor
|
38
|
+
flags |= COMPRESSED_FLAG
|
39
|
+
value = @compressor.compress(value)
|
40
|
+
end
|
41
|
+
flags |= RAW_FLAG if flags == 0
|
42
|
+
[value, flags]
|
43
|
+
end
|
44
|
+
|
45
|
+
def decode(_key, value, flags)
|
46
|
+
if (flags & COMPRESSED_FLAG) != 0
|
47
|
+
value = @compressor.decompress(value)
|
48
|
+
end
|
49
|
+
|
50
|
+
if (flags & SERIALIZED_FLAG) != 0
|
51
|
+
@serializer.load(value)
|
52
|
+
elsif flags == 0 # legacy cache value
|
53
|
+
@serializer.load(value) rescue value
|
54
|
+
else
|
55
|
+
value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
16
60
|
attr_accessor :read_only, :swallow_exceptions
|
17
|
-
attr_writer :on_error
|
18
61
|
|
19
|
-
|
62
|
+
prepend(Strategy::LocalCache)
|
63
|
+
|
64
|
+
def initialize(*addresses, **options)
|
20
65
|
addresses = addresses.flatten
|
21
|
-
options
|
66
|
+
options[:codec] ||= Codec.new
|
22
67
|
@swallow_exceptions = true
|
23
68
|
@swallow_exceptions = options.delete(:swallow_exceptions) if options.key?(:swallow_exceptions)
|
24
69
|
|
25
|
-
|
70
|
+
if options.key?(:coder)
|
71
|
+
raise ArgumentError, "ActiveSupport::Cache::MemcachedStore doesn't support custom coders"
|
72
|
+
end
|
73
|
+
|
74
|
+
# We don't use a coder, so we set it to nil so Active Support don't think we're using
|
75
|
+
# a deprecated one.
|
76
|
+
super(options.merge(coder: nil))
|
26
77
|
|
27
78
|
if addresses.first.is_a?(Memcached)
|
28
|
-
@
|
79
|
+
@connection = addresses.first
|
29
80
|
raise "Memcached::Rails is no longer supported, "\
|
30
|
-
"use a Memcached instance instead" if @
|
81
|
+
"use a Memcached instance instead" if @connection.is_a?(Memcached::Rails)
|
31
82
|
else
|
32
83
|
mem_cache_options = options.dup
|
33
84
|
servers = mem_cache_options.delete(:servers)
|
34
85
|
UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
|
35
|
-
@
|
86
|
+
@connection = Memcached.new([*addresses, *servers], mem_cache_options)
|
36
87
|
end
|
37
|
-
|
38
|
-
extend Strategy::LocalCache
|
39
88
|
end
|
40
89
|
|
41
|
-
def
|
42
|
-
return
|
43
|
-
|
90
|
+
def append(name, value, options = nil)
|
91
|
+
return true if read_only
|
92
|
+
options = merged_options(options)
|
93
|
+
normalized_key = normalize_key(name, options)
|
94
|
+
|
95
|
+
handle_exceptions(return_value_on_error: nil, on_miss: false, miss_exceptions: [Memcached::NotStored]) do
|
96
|
+
instrument(:append, name) do
|
97
|
+
@connection.append(normalized_key, value)
|
98
|
+
end
|
99
|
+
true
|
100
|
+
end
|
44
101
|
end
|
45
102
|
|
46
103
|
def write(*)
|
@@ -63,7 +120,7 @@ module ActiveSupport
|
|
63
120
|
|
64
121
|
handle_exceptions(return_value_on_error: {}) do
|
65
122
|
instrument(:read_multi, names, options) do
|
66
|
-
if raw_values = @
|
123
|
+
if raw_values = @connection.get(keys_to_names.keys)
|
67
124
|
raw_values.each do |key, value|
|
68
125
|
entry = deserialize_entry(value)
|
69
126
|
values[keys_to_names[key]] = entry.value unless entry.expired?
|
@@ -77,30 +134,40 @@ module ActiveSupport
|
|
77
134
|
def cas(name, options = nil)
|
78
135
|
options = merged_options(options)
|
79
136
|
key = normalize_key(name, options)
|
137
|
+
payload = nil
|
80
138
|
|
81
|
-
handle_exceptions(return_value_on_error: false) do
|
139
|
+
success = handle_exceptions(return_value_on_error: false) do
|
82
140
|
instrument(:cas, name, options) do
|
83
|
-
@
|
141
|
+
@connection.cas(key, expiration(options)) do |raw_value|
|
84
142
|
entry = deserialize_entry(raw_value)
|
85
143
|
value = yield entry.value
|
86
144
|
break true if read_only
|
87
|
-
serialize_entry(Entry.new(value, options), options)
|
145
|
+
payload = serialize_entry(Entry.new(value, **options), options)
|
88
146
|
end
|
89
147
|
end
|
90
148
|
true
|
91
149
|
end
|
150
|
+
|
151
|
+
if success
|
152
|
+
local_cache.write_entry(key, payload) if local_cache
|
153
|
+
else
|
154
|
+
local_cache.delete_entry(key) if local_cache
|
155
|
+
end
|
156
|
+
|
157
|
+
success
|
92
158
|
end
|
93
159
|
|
94
|
-
def cas_multi(*names)
|
95
|
-
options = names.extract_options!
|
160
|
+
def cas_multi(*names, **options)
|
96
161
|
return if names.empty?
|
97
162
|
|
98
163
|
options = merged_options(options)
|
99
164
|
keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
|
100
165
|
|
166
|
+
sent_payloads = nil
|
167
|
+
|
101
168
|
handle_exceptions(return_value_on_error: false) do
|
102
169
|
instrument(:cas_multi, names, options) do
|
103
|
-
@
|
170
|
+
written_payloads = @connection.cas(keys_to_names.keys, expiration(options)) do |raw_values|
|
104
171
|
values = {}
|
105
172
|
|
106
173
|
raw_values.each do |key, raw_value|
|
@@ -113,11 +180,22 @@ module ActiveSupport
|
|
113
180
|
break true if read_only
|
114
181
|
|
115
182
|
serialized_values = values.map do |name, value|
|
116
|
-
[normalize_key(name, options), serialize_entry(Entry.new(value, options), options)
|
183
|
+
[normalize_key(name, options), serialize_entry(Entry.new(value, **options), options)]
|
117
184
|
end
|
118
185
|
|
119
|
-
Hash[serialized_values]
|
186
|
+
sent_payloads = Hash[serialized_values]
|
120
187
|
end
|
188
|
+
|
189
|
+
if local_cache && sent_payloads
|
190
|
+
sent_payloads.each_key do |key|
|
191
|
+
if written_payloads.key?(key)
|
192
|
+
local_cache.write_entry(key, written_payloads[key])
|
193
|
+
else
|
194
|
+
local_cache.delete_entry(key)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
121
199
|
true
|
122
200
|
end
|
123
201
|
end
|
@@ -127,7 +205,7 @@ module ActiveSupport
|
|
127
205
|
options = merged_options(options)
|
128
206
|
handle_exceptions(return_value_on_error: nil) do
|
129
207
|
instrument(:increment, name, amount: amount) do
|
130
|
-
@
|
208
|
+
@connection.incr(normalize_key(name, options), amount)
|
131
209
|
end
|
132
210
|
end
|
133
211
|
end
|
@@ -136,20 +214,20 @@ module ActiveSupport
|
|
136
214
|
options = merged_options(options)
|
137
215
|
handle_exceptions(return_value_on_error: nil) do
|
138
216
|
instrument(:decrement, name, amount: amount) do
|
139
|
-
@
|
217
|
+
@connection.decr(normalize_key(name, options), amount)
|
140
218
|
end
|
141
219
|
end
|
142
220
|
end
|
143
221
|
|
144
222
|
def clear(options = nil)
|
145
223
|
ActiveSupport::Notifications.instrument("cache_clear.active_support", options || {}) do
|
146
|
-
@
|
224
|
+
@connection.flush
|
147
225
|
end
|
148
226
|
end
|
149
227
|
|
150
228
|
def stats
|
151
229
|
ActiveSupport::Notifications.instrument("cache_stats.active_support") do
|
152
|
-
@
|
230
|
+
@connection.stats
|
153
231
|
end
|
154
232
|
end
|
155
233
|
|
@@ -159,104 +237,156 @@ module ActiveSupport
|
|
159
237
|
|
160
238
|
def reset #:nodoc:
|
161
239
|
handle_exceptions(return_value_on_error: false) do
|
162
|
-
@
|
240
|
+
@connection.reset
|
163
241
|
end
|
164
242
|
end
|
165
243
|
|
166
|
-
|
244
|
+
private
|
245
|
+
|
246
|
+
if private_method_defined?(:read_serialized_entry)
|
247
|
+
class DupLocalStore < DelegateClass(Strategy::LocalCache::LocalStore)
|
248
|
+
def write_entry(_key, entry)
|
249
|
+
if entry.is_a?(Entry)
|
250
|
+
entry.dup_value!
|
251
|
+
end
|
252
|
+
super
|
253
|
+
end
|
167
254
|
|
168
|
-
|
169
|
-
|
170
|
-
|
255
|
+
def fetch_entry(key)
|
256
|
+
entry = super do
|
257
|
+
new_entry = yield
|
258
|
+
if entry.is_a?(Entry)
|
259
|
+
new_entry.dup_value!
|
260
|
+
end
|
261
|
+
new_entry
|
262
|
+
end
|
263
|
+
entry = entry.dup
|
264
|
+
|
265
|
+
if entry.is_a?(Entry)
|
266
|
+
entry.dup_value!
|
267
|
+
end
|
268
|
+
|
269
|
+
entry
|
270
|
+
end
|
171
271
|
end
|
172
|
-
end
|
173
272
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
273
|
+
module DupLocalCache
|
274
|
+
private
|
275
|
+
|
276
|
+
def local_cache
|
277
|
+
if local_cache = super
|
278
|
+
DupLocalStore.new(local_cache)
|
279
|
+
end
|
280
|
+
end
|
182
281
|
end
|
183
|
-
end
|
184
282
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
true
|
283
|
+
prepend DupLocalCache
|
284
|
+
|
285
|
+
def read_entry(key, **options) # :nodoc:
|
286
|
+
deserialize_entry(read_serialized_entry(key, **options))
|
190
287
|
end
|
191
|
-
end
|
192
288
|
|
193
|
-
|
289
|
+
def read_serialized_entry(key, **)
|
290
|
+
handle_exceptions(return_value_on_error: nil) do
|
291
|
+
@connection.get(key)
|
292
|
+
end
|
293
|
+
end
|
194
294
|
|
195
|
-
|
196
|
-
|
197
|
-
|
295
|
+
def write_entry(key, entry, **options) # :nodoc:
|
296
|
+
return true if read_only
|
297
|
+
|
298
|
+
write_serialized_entry(key, serialize_entry(entry, **options), **options)
|
198
299
|
end
|
199
300
|
|
200
|
-
def
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
301
|
+
def write_serialized_entry(key, value, **options)
|
302
|
+
method = options && options[:unless_exist] ? :add : :set
|
303
|
+
expires_in = expiration(options)
|
304
|
+
handle_exceptions(return_value_on_error: false) do
|
305
|
+
@connection.send(method, key, value, expires_in)
|
306
|
+
true
|
307
|
+
end
|
206
308
|
end
|
207
309
|
else
|
208
|
-
def
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
|
213
|
-
key
|
310
|
+
def read_entry(key, _options) # :nodoc:
|
311
|
+
handle_exceptions(return_value_on_error: nil) do
|
312
|
+
deserialize_entry(@connection.get(key))
|
313
|
+
end
|
214
314
|
end
|
215
315
|
|
216
|
-
def
|
217
|
-
|
316
|
+
def write_entry(key, entry, options) # :nodoc:
|
317
|
+
return true if read_only
|
318
|
+
method = options && options[:unless_exist] ? :add : :set
|
319
|
+
expires_in = expiration(options)
|
320
|
+
value = serialize_entry(entry, options)
|
321
|
+
handle_exceptions(return_value_on_error: false) do
|
322
|
+
@connection.send(method, key, value, expires_in)
|
323
|
+
true
|
324
|
+
end
|
218
325
|
end
|
219
326
|
end
|
220
327
|
|
221
|
-
def
|
222
|
-
if
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
raw_value
|
227
|
-
end
|
228
|
-
entry.is_a?(Entry) ? entry : Entry.new(entry)
|
328
|
+
def delete_entry(key, _options = nil) # :nodoc:
|
329
|
+
return true if read_only
|
330
|
+
handle_exceptions(return_value_on_error: false, on_miss: true) do
|
331
|
+
@connection.delete(key)
|
332
|
+
true
|
229
333
|
end
|
230
334
|
end
|
231
335
|
|
232
|
-
|
233
|
-
|
234
|
-
|
336
|
+
private
|
337
|
+
|
338
|
+
def normalize_key(key, options)
|
339
|
+
key = super.dup
|
340
|
+
key = key.force_encoding(Encoding::ASCII_8BIT)
|
341
|
+
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
|
342
|
+
# When we remove support to Rails 5.1 we can change the code to use ActiveSupport::Digest
|
343
|
+
key = "#{key[0, 213]}:md5:#{::Digest::MD5.hexdigest(key)}" if key.size > 250
|
344
|
+
key
|
345
|
+
end
|
346
|
+
|
347
|
+
def deserialize_entry(value)
|
348
|
+
unless value.nil?
|
349
|
+
value.is_a?(Entry) ? value : Entry.new(value, compress: false)
|
350
|
+
end
|
235
351
|
end
|
236
352
|
|
237
|
-
def
|
238
|
-
options[:raw]
|
353
|
+
def serialize_entry(entry, options = nil)
|
354
|
+
if options && options[:raw]
|
355
|
+
entry.value.to_s
|
356
|
+
else
|
357
|
+
entry
|
358
|
+
end
|
239
359
|
end
|
240
360
|
|
241
361
|
def expiration(options)
|
242
362
|
expires_in = options[:expires_in].to_i
|
243
|
-
if expires_in > 0 && !options[:raw]
|
244
|
-
|
245
|
-
expires_in += 5.minutes.to_i
|
363
|
+
if expires_in > 0 && options[:race_condition_ttl] && !options[:raw]
|
364
|
+
expires_in += options[:race_condition_ttl].to_i
|
246
365
|
end
|
247
366
|
expires_in
|
248
367
|
end
|
249
368
|
|
250
|
-
def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error)
|
369
|
+
def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error, miss_exceptions: [])
|
251
370
|
yield
|
252
|
-
rescue Memcached::NotFound, Memcached::ConnectionDataExists
|
371
|
+
rescue Memcached::NotFound, Memcached::ConnectionDataExists, *miss_exceptions
|
253
372
|
on_miss
|
254
373
|
rescue Memcached::Error => e
|
255
|
-
|
374
|
+
log_warning(e)
|
256
375
|
raise unless @swallow_exceptions
|
257
|
-
logger.warn("memcached error: #{e.class}: #{e.message}") if logger
|
258
376
|
return_value_on_error
|
259
377
|
end
|
378
|
+
|
379
|
+
def log_warning(err)
|
380
|
+
return unless logger
|
381
|
+
return if err.is_a?(Memcached::NotStored) && @swallow_exceptions
|
382
|
+
|
383
|
+
logger.warn(
|
384
|
+
"[MEMCACHED_ERROR] swallowed=#{@swallow_exceptions}" \
|
385
|
+
" exception_class=#{err.class} exception_message=#{err.message}"
|
386
|
+
)
|
387
|
+
end
|
388
|
+
|
389
|
+
ActiveSupport.run_load_hooks(:memcached_store)
|
260
390
|
end
|
261
391
|
end
|
262
392
|
end
|
data/lib/memcached_store.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memcached_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Camilo Lopez
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2023-10-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -19,28 +19,28 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '6'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '6'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: memcached
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
34
|
- - "~>"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 1.8
|
36
|
+
version: '1.8'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.8
|
43
|
+
version: '1.8'
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: rake
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,6 +55,34 @@ dependencies:
|
|
55
55
|
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '0'
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: mocha
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: timecop
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
58
86
|
description: Plugin-able Memcached adapters to add features (compression, safety)
|
59
87
|
email:
|
60
88
|
- camilo@camilolopez.com
|
@@ -70,11 +98,13 @@ files:
|
|
70
98
|
- lib/active_support/cache/memcached_snappy_store.rb
|
71
99
|
- lib/active_support/cache/memcached_store.rb
|
72
100
|
- lib/memcached_store.rb
|
101
|
+
- lib/memcached_store/railtie.rb
|
73
102
|
- lib/memcached_store/version.rb
|
74
103
|
homepage: https://github.com/Shopify/memcached_store/
|
75
104
|
licenses:
|
76
105
|
- MIT
|
77
|
-
metadata:
|
106
|
+
metadata:
|
107
|
+
allowed_push_host: https://rubygems.org
|
78
108
|
post_install_message:
|
79
109
|
rdoc_options: []
|
80
110
|
require_paths:
|
@@ -83,15 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
113
|
requirements:
|
84
114
|
- - ">="
|
85
115
|
- !ruby/object:Gem::Version
|
86
|
-
version: 2.
|
116
|
+
version: 2.6.0
|
87
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
118
|
requirements:
|
89
119
|
- - ">="
|
90
120
|
- !ruby/object:Gem::Version
|
91
121
|
version: '0'
|
92
122
|
requirements: []
|
93
|
-
|
94
|
-
rubygems_version: 2.5.2.1
|
123
|
+
rubygems_version: 3.4.20
|
95
124
|
signing_key:
|
96
125
|
specification_version: 4
|
97
126
|
summary: Plugin-able Memcached adapters to add features (compression, safety)
|