memcached_store 2.0.1 → 2.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: aa72b41fd6b6cb58a042294012e8f736c3b5ef62
4
- data.tar.gz: e053cc731f76cb2bc909e36f7f004002b2fd7e38
2
+ SHA256:
3
+ metadata.gz: 4635e49b33c70f622363339dda844ed847785724779b9fa7820d4a34dbf372f8
4
+ data.tar.gz: 2371f00c595f4b9fb5f4fd37621a591e8ac11125b53467dbbd990febfa9296d9
5
5
  SHA512:
6
- metadata.gz: 2045826e00f5d2c2d988eed051036713348bafcd7867bf06b1f6760decea9719e62a0cfc332ee82f3e3ef84f2eecb65ab7eba373f1e969f5592cfa53eb12a034
7
- data.tar.gz: c36fde971c9abc498626b8662cb87977369e85c3818efbbb5bf23bf0ec0bf51e9a17e338dce98661c41b7fdb2abbf7fc6a1a271bea0cb0a8fd177e8f9e5dccf7
6
+ metadata.gz: 18831e059e7db2fae9d3733baa244f2ba69050bfc1d72ecd72dd80332a0e525b50a409f98cb76d224450fce01919e29695ba3c5585cadc42bfaef1b66474ac72
7
+ data.tar.gz: cc44c59b08101ac3934ce59b90c89179d0b88c64dd519d265b81e76adbb09c8d3e2f5b4445e7de6e8c73973df615c46a613a29dd5f9c0db8acfa6d2c788d4445
@@ -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
- private
29
-
30
- def serialize_entry(entry, options)
31
- value = options[:raw] ? entry.value.to_s : Marshal.dump(entry)
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
@@ -13,30 +13,86 @@ module ActiveSupport
13
13
  class MemcachedStore < Store
14
14
  ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
15
15
 
16
+ class Codec
17
+ # use dalli compatible flags
18
+ SERIALIZED_FLAG = 0x1
19
+ COMPRESSED_FLAG = 0x2
20
+
21
+ # Older versions of this gem would use 0 for the flags whether or not
22
+ # the value was marshal dumped. By setting this flag, we can tell if
23
+ # it were set with an older version for backwards compatible decoding.
24
+ RAW_FLAG = 0x10
25
+
26
+ def initialize(serializer: Marshal, compressor: nil)
27
+ @serializer = serializer
28
+ @compressor = compressor
29
+ end
30
+
31
+ def encode(_key, value, flags)
32
+ unless value.is_a?(String)
33
+ flags |= SERIALIZED_FLAG
34
+ value = @serializer.dump(value)
35
+ end
36
+ if @compressor
37
+ flags |= COMPRESSED_FLAG
38
+ value = @compressor.compress(value)
39
+ end
40
+ flags |= RAW_FLAG if flags == 0
41
+ [value, flags]
42
+ end
43
+
44
+ def decode(_key, value, flags)
45
+ if (flags & COMPRESSED_FLAG) != 0
46
+ value = @compressor.decompress(value)
47
+ end
48
+
49
+ if (flags & SERIALIZED_FLAG) != 0
50
+ @serializer.load(value)
51
+ elsif flags == 0 # legacy cache value
52
+ @serializer.load(value) rescue value
53
+ else
54
+ value
55
+ end
56
+ end
57
+ end
58
+
16
59
  attr_accessor :read_only, :swallow_exceptions
17
60
 
18
- def initialize(*addresses)
61
+ def initialize(*addresses, **options)
19
62
  addresses = addresses.flatten
20
- options = addresses.extract_options!
63
+ options[:codec] ||= Codec.new
21
64
  @swallow_exceptions = true
22
65
  @swallow_exceptions = options.delete(:swallow_exceptions) if options.key?(:swallow_exceptions)
23
66
 
24
67
  super(options)
25
68
 
26
69
  if addresses.first.is_a?(Memcached)
27
- @data = addresses.first
70
+ @connection = addresses.first
28
71
  raise "Memcached::Rails is no longer supported, "\
29
- "use a Memcached instance instead" if @data.is_a?(Memcached::Rails)
72
+ "use a Memcached instance instead" if @connection.is_a?(Memcached::Rails)
30
73
  else
31
74
  mem_cache_options = options.dup
32
75
  servers = mem_cache_options.delete(:servers)
33
76
  UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
34
- @data = Memcached.new([*addresses, *servers], mem_cache_options)
77
+ @connection = Memcached.new([*addresses, *servers], mem_cache_options)
35
78
  end
36
79
 
37
80
  extend Strategy::LocalCache
38
81
  end
39
82
 
83
+ def append(name, value, options = nil)
84
+ return true if read_only
85
+ options = merged_options(options)
86
+ normalized_key = normalize_key(name, options)
87
+
88
+ handle_exceptions(return_value_on_error: nil, on_miss: false, miss_exceptions: [Memcached::NotStored]) do
89
+ instrument(:append, name) do
90
+ @connection.append(normalized_key, value)
91
+ end
92
+ true
93
+ end
94
+ end
95
+
40
96
  def write(*)
41
97
  return true if read_only
42
98
  super
@@ -57,7 +113,7 @@ module ActiveSupport
57
113
 
58
114
  handle_exceptions(return_value_on_error: {}) do
59
115
  instrument(:read_multi, names, options) do
60
- if raw_values = @data.get(keys_to_names.keys, false)
116
+ if raw_values = @connection.get(keys_to_names.keys)
61
117
  raw_values.each do |key, value|
62
118
  entry = deserialize_entry(value)
63
119
  values[keys_to_names[key]] = entry.value unless entry.expired?
@@ -74,19 +130,18 @@ module ActiveSupport
74
130
 
75
131
  handle_exceptions(return_value_on_error: false) do
76
132
  instrument(:cas, name, options) do
77
- @data.cas(key, expiration(options), !cas_raw?(options)) do |raw_value|
133
+ @connection.cas(key, expiration(options)) do |raw_value|
78
134
  entry = deserialize_entry(raw_value)
79
135
  value = yield entry.value
80
136
  break true if read_only
81
- serialize_entry(Entry.new(value, options), options).first
137
+ serialize_entry(Entry.new(value, **options), options)
82
138
  end
83
139
  end
84
140
  true
85
141
  end
86
142
  end
87
143
 
88
- def cas_multi(*names)
89
- options = names.extract_options!
144
+ def cas_multi(*names, **options)
90
145
  return if names.empty?
91
146
 
92
147
  options = merged_options(options)
@@ -94,7 +149,7 @@ module ActiveSupport
94
149
 
95
150
  handle_exceptions(return_value_on_error: false) do
96
151
  instrument(:cas_multi, names, options) do
97
- @data.cas(keys_to_names.keys, expiration(options), !cas_raw?(options)) do |raw_values|
152
+ @connection.cas(keys_to_names.keys, expiration(options)) do |raw_values|
98
153
  values = {}
99
154
 
100
155
  raw_values.each do |key, raw_value|
@@ -107,7 +162,7 @@ module ActiveSupport
107
162
  break true if read_only
108
163
 
109
164
  serialized_values = values.map do |name, value|
110
- [normalize_key(name, options), serialize_entry(Entry.new(value, options), options).first]
165
+ [normalize_key(name, options), serialize_entry(Entry.new(value, **options), options)]
111
166
  end
112
167
 
113
168
  Hash[serialized_values]
@@ -121,7 +176,7 @@ module ActiveSupport
121
176
  options = merged_options(options)
122
177
  handle_exceptions(return_value_on_error: nil) do
123
178
  instrument(:increment, name, amount: amount) do
124
- @data.incr(normalize_key(name, options), amount)
179
+ @connection.incr(normalize_key(name, options), amount)
125
180
  end
126
181
  end
127
182
  end
@@ -130,20 +185,20 @@ module ActiveSupport
130
185
  options = merged_options(options)
131
186
  handle_exceptions(return_value_on_error: nil) do
132
187
  instrument(:decrement, name, amount: amount) do
133
- @data.decr(normalize_key(name, options), amount)
188
+ @connection.decr(normalize_key(name, options), amount)
134
189
  end
135
190
  end
136
191
  end
137
192
 
138
193
  def clear(options = nil)
139
194
  ActiveSupport::Notifications.instrument("cache_clear.active_support", options || {}) do
140
- @data.flush
195
+ @connection.flush
141
196
  end
142
197
  end
143
198
 
144
199
  def stats
145
200
  ActiveSupport::Notifications.instrument("cache_stats.active_support") do
146
- @data.stats
201
+ @connection.stats
147
202
  end
148
203
  end
149
204
 
@@ -153,7 +208,7 @@ module ActiveSupport
153
208
 
154
209
  def reset #:nodoc:
155
210
  handle_exceptions(return_value_on_error: false) do
156
- @data.reset
211
+ @connection.reset
157
212
  end
158
213
  end
159
214
 
@@ -161,7 +216,7 @@ module ActiveSupport
161
216
 
162
217
  def read_entry(key, _options) # :nodoc:
163
218
  handle_exceptions(return_value_on_error: nil) do
164
- deserialize_entry(@data.get(escape_key(key), false))
219
+ deserialize_entry(@connection.get(escape_key(key)))
165
220
  end
166
221
  end
167
222
 
@@ -169,9 +224,9 @@ module ActiveSupport
169
224
  return true if read_only
170
225
  method = options && options[:unless_exist] ? :add : :set
171
226
  expires_in = expiration(options)
172
- value, raw = serialize_entry(entry, options)
227
+ value = serialize_entry(entry, options)
173
228
  handle_exceptions(return_value_on_error: false) do
174
- @data.send(method, escape_key(key), value, expires_in, !raw)
229
+ @connection.send(method, escape_key(key), value, expires_in)
175
230
  true
176
231
  end
177
232
  end
@@ -179,7 +234,7 @@ module ActiveSupport
179
234
  def delete_entry(key, _options) # :nodoc:
180
235
  return true if read_only
181
236
  handle_exceptions(return_value_on_error: false, on_miss: true) do
182
- @data.delete(escape_key(key))
237
+ @connection.delete(escape_key(key))
183
238
  true
184
239
  end
185
240
  end
@@ -213,38 +268,31 @@ module ActiveSupport
213
268
  end
214
269
  end
215
270
 
216
- def deserialize_entry(raw_value)
217
- if raw_value
218
- entry = begin
219
- Marshal.load(raw_value)
220
- rescue
221
- raw_value
222
- end
223
- entry.is_a?(Entry) ? entry : Entry.new(entry)
271
+ def deserialize_entry(value)
272
+ if value
273
+ value.is_a?(Entry) ? value : Entry.new(value, compress: false)
224
274
  end
225
275
  end
226
276
 
227
277
  def serialize_entry(entry, options)
228
- entry = entry.value.to_s if options[:raw]
229
- [entry, options[:raw]]
230
- end
231
-
232
- def cas_raw?(options)
233
- options[:raw]
278
+ if options[:raw]
279
+ entry.value.to_s
280
+ else
281
+ entry
282
+ end
234
283
  end
235
284
 
236
285
  def expiration(options)
237
286
  expires_in = options[:expires_in].to_i
238
- if expires_in > 0 && !options[:raw]
239
- # Set the memcache expire a few minutes in the future to support race condition ttls on read
240
- expires_in += 5.minutes.to_i
287
+ if expires_in > 0 && options[:race_condition_ttl] && !options[:raw]
288
+ expires_in += options[:race_condition_ttl].to_i
241
289
  end
242
290
  expires_in
243
291
  end
244
292
 
245
- def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error)
293
+ def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error, miss_exceptions: [])
246
294
  yield
247
- rescue Memcached::NotFound, Memcached::ConnectionDataExists
295
+ rescue Memcached::NotFound, Memcached::ConnectionDataExists, *miss_exceptions
248
296
  on_miss
249
297
  rescue Memcached::Error => e
250
298
  log_warning(e)
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module MemcachedStore
3
- VERSION = "2.0.1"
3
+ VERSION = "2.1.5"
4
4
  end
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: 2.0.1
4
+ version: 2.1.5
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: 2018-08-23 00:00:00.000000000 Z
14
+ date: 2020-05-25 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -75,7 +75,8 @@ files:
75
75
  homepage: https://github.com/Shopify/memcached_store/
76
76
  licenses:
77
77
  - MIT
78
- metadata: {}
78
+ metadata:
79
+ allowed_push_host: https://rubygems.org
79
80
  post_install_message:
80
81
  rdoc_options: []
81
82
  require_paths:
@@ -91,8 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
92
  - !ruby/object:Gem::Version
92
93
  version: '0'
93
94
  requirements: []
94
- rubyforge_project:
95
- rubygems_version: 2.6.14
95
+ rubygems_version: 3.0.3
96
96
  signing_key:
97
97
  specification_version: 4
98
98
  summary: Plugin-able Memcached adapters to add features (compression, safety)