memcached_store 0.12.8 → 1.0.0

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
2
  SHA1:
3
- metadata.gz: 3e458052cfc2aac92c629b37e02fc7ae66077dcd
4
- data.tar.gz: af048ce101065d5bc3463a9e118b6c3fb45c7763
3
+ metadata.gz: 0915f7c2305d9b4962115d99c52997673e711a58
4
+ data.tar.gz: 0cc5bbca84c1aee1bcf70f782735d90cd562252d
5
5
  SHA512:
6
- metadata.gz: 376570dd86abe4ca47cff7cb74aa934c7b26dac30ad24eeab5ee02b8310a24d9866d8c92ba2c85364c9c7bec426fe842e282b65d84742f2ba371db2cef478254
7
- data.tar.gz: 8d958e238be593341eb041916ee4b47648a841ef3c87f45a3ebeeb1a2bca09808c43b1cf16aaf0ae5dba0b842ce49300ea9a3d600621e7f26d3deaeaa223b761
6
+ metadata.gz: b8a0873627bf43775afd6ef3a7aeb9788a3b5d96d82eaac63f3a49879942e43daf9ace73d8c90c697fc0ca4a4f8a6ee777b3314339634c18734953c84e065d94
7
+ data.tar.gz: 5326f2375fa65be54b8c0f5a9c163e0a606c8f6a474ee21f7476c8175fa39252813392e206ad599494b3b72251b6054ad8c824024e963dd9addc3ea16316513c
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Camilo Lopez
1
+ Copyright (c) 2013-2016 Shopify Inc.
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -8,7 +8,7 @@ ActiveSupport memcached store. This wraps the memcached gem into a ActiveSupport
8
8
 
9
9
  ### MemcachedSnappyStore
10
10
 
11
- ActiveSupport cache store that adds snappy compression at the cost of making the ```incr, decr``` operations unavailable.
11
+ ActiveSupport cache store that adds snappy compression at the cost of making the `incr, decr` operations unavailable.
12
12
 
13
13
  ## Installation
14
14
 
@@ -40,9 +40,13 @@ config.cache_store = :memcached_store,
40
40
 
41
41
  # for snappy store
42
42
  config.cache_store = :memcached_snappy_store,
43
- Memcached::Rails.new(:servers => ['memcached1.foo.com', 'memcached2.foo.com'])
43
+ Memcached::Rails.new(servers: ['memcached1.foo.com', 'memcached2.foo.com'])
44
44
  ```
45
45
 
46
+ ## Benchmarks
47
+
48
+ For benchmarks please refer to https://github.com/basecamp/memcached_bench.
49
+
46
50
  ## Code status
47
51
 
48
52
  [![Build Status](https://travis-ci.org/Shopify/memcached_store.svg?branch=master)](https://travis-ci.org/Shopify/memcached_store)
@@ -12,12 +12,12 @@ module ActiveSupport
12
12
  class MemcachedSnappyStore < MemcachedStore
13
13
  class UnsupportedOperation < StandardError; end
14
14
 
15
- def increment(*args)
16
- raise UnsupportedOperation.new("increment is not supported by: #{self.class.name}")
15
+ def increment(*)
16
+ raise UnsupportedOperation, "increment is not supported by: #{self.class.name}"
17
17
  end
18
18
 
19
- def decrement(*args)
20
- raise UnsupportedOperation.new("decrement is not supported by: #{self.class.name}")
19
+ def decrement(*)
20
+ raise UnsupportedOperation, "decrement is not supported by: #{self.class.name}"
21
21
  end
22
22
 
23
23
  # IdentityCache has its own handling for read only.
@@ -26,6 +26,7 @@ module ActiveSupport
26
26
  end
27
27
 
28
28
  private
29
+
29
30
  def serialize_entry(entry, options)
30
31
  value = options[:raw] ? entry.value.to_s : Marshal.dump(entry)
31
32
  [Snappy.deflate(value), true]
@@ -34,12 +35,10 @@ module ActiveSupport
34
35
  def deserialize_entry(compressed_value)
35
36
  if compressed_value
36
37
  super(Snappy.inflate(compressed_value))
37
- else
38
- nil
39
38
  end
40
39
  end
41
40
 
42
- def cas_raw?(options)
41
+ def cas_raw?(_options)
43
42
  true
44
43
  end
45
44
  end
@@ -11,21 +11,20 @@ module ActiveSupport
11
11
  # MemcachedStore implements the Strategy::LocalCache strategy which implements
12
12
  # an in-memory cache inside of a block.
13
13
  class MemcachedStore < Store
14
- FATAL_EXCEPTIONS = [ Memcached::ABadKeyWasProvidedOrCharactersOutOfRange,
15
- Memcached::AKeyLengthOfZeroWasProvided,
16
- Memcached::ConnectionBindFailure,
17
- Memcached::ConnectionDataDoesNotExist,
18
- Memcached::ConnectionFailure,
19
- Memcached::ConnectionSocketCreateFailure,
20
- Memcached::CouldNotOpenUnixSocket,
21
- Memcached::NoServersDefined,
22
- Memcached::TheHostTransportProtocolDoesNotMatchThatOfTheClient
23
- ]
24
-
25
- if defined?(::Rails) && ::Rails.env.test?
26
- NONFATAL_EXCEPTIONS = []
14
+ FATAL_EXCEPTIONS = [Memcached::ABadKeyWasProvidedOrCharactersOutOfRange,
15
+ Memcached::AKeyLengthOfZeroWasProvided,
16
+ Memcached::ConnectionBindFailure,
17
+ Memcached::ConnectionDataDoesNotExist,
18
+ Memcached::ConnectionFailure,
19
+ Memcached::ConnectionSocketCreateFailure,
20
+ Memcached::CouldNotOpenUnixSocket,
21
+ Memcached::NoServersDefined,
22
+ Memcached::TheHostTransportProtocolDoesNotMatchThatOfTheClient]
23
+
24
+ NONFATAL_EXCEPTIONS = if defined?(::Rails) && ::Rails.env.test?
25
+ []
27
26
  else
28
- NONFATAL_EXCEPTIONS = Memcached::EXCEPTIONS - FATAL_EXCEPTIONS
27
+ Memcached::EXCEPTIONS - FATAL_EXCEPTIONS
29
28
  end
30
29
 
31
30
  ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
@@ -41,7 +40,7 @@ module ActiveSupport
41
40
  @data = addresses.first
42
41
  else
43
42
  mem_cache_options = options.dup
44
- UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
43
+ UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
45
44
  @data = Memcached::Rails.new(*(addresses + [mem_cache_options]))
46
45
  end
47
46
 
@@ -53,24 +52,24 @@ module ActiveSupport
53
52
  @logger = ::Rails.logger if defined?(::Rails)
54
53
  end
55
54
 
56
- def write(*args)
55
+ def write(*)
57
56
  return true if read_only
58
- super(*args)
57
+ super
59
58
  end
60
59
 
61
- def delete(*args)
60
+ def delete(*)
62
61
  return true if read_only
63
- super(*args)
62
+ super
64
63
  end
65
64
 
66
65
  def read_multi(*names)
67
66
  options = names.extract_options!
68
67
  options = merged_options(options)
69
- keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
68
+ keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
70
69
  values = {}
71
70
 
72
71
  instrument(:read_multi, names, options) do
73
- if raw_values = @data.get_multi(keys_to_names.keys, :raw => true)
72
+ if raw_values = @data.get_multi(keys_to_names.keys, raw: true)
74
73
  raw_values.each do |key, value|
75
74
  entry = deserialize_entry(value)
76
75
  values[keys_to_names[key]] = entry.value unless entry.expired?
@@ -85,7 +84,7 @@ module ActiveSupport
85
84
 
86
85
  def cas(name, options = nil)
87
86
  options = merged_options(options)
88
- key = namespaced_key(name, options)
87
+ key = normalize_key(name, options)
89
88
 
90
89
  instrument(:cas, name, options) do
91
90
  @data.cas(key, expiration(options), cas_raw?(options)) do |raw_value|
@@ -101,21 +100,30 @@ module ActiveSupport
101
100
  end
102
101
 
103
102
  def cas_multi(*names)
104
-
105
103
  options = names.extract_options!
104
+ return if names.empty?
105
+
106
106
  options = merged_options(options)
107
- keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
107
+ keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
108
108
 
109
109
  instrument(:cas_multi, names, options) do
110
110
  @data.cas(keys_to_names.keys, expiration(options), cas_raw?(options)) do |raw_values|
111
111
  values = {}
112
+
112
113
  raw_values.each do |key, raw_value|
113
114
  entry = deserialize_entry(raw_value)
114
115
  values[keys_to_names[key]] = entry.value unless entry.expired?
115
116
  end
117
+
116
118
  values = yield values
119
+
117
120
  break true if read_only
118
- Hash[values.map{|name, value| [escape_key(namespaced_key(name, options)), serialize_entry(Entry.new(value, options), options).first]}]
121
+
122
+ serialized_values = values.map do |name, value|
123
+ [normalize_key(name, options), serialize_entry(Entry.new(value, options), options).first]
124
+ end
125
+
126
+ Hash[serialized_values]
119
127
  end
120
128
  end
121
129
  rescue *NONFATAL_EXCEPTIONS => e
@@ -125,8 +133,8 @@ module ActiveSupport
125
133
 
126
134
  def increment(name, amount = 1, options = nil) # :nodoc:
127
135
  options = merged_options(options)
128
- instrument(:increment, name, :amount => amount) do
129
- @data.incr(escape_key(namespaced_key(name, options)), amount)
136
+ instrument(:increment, name, amount: amount) do
137
+ @data.incr(normalize_key(name, options), amount)
130
138
  end
131
139
  rescue *NONFATAL_EXCEPTIONS => e
132
140
  @data.log_exception(e)
@@ -135,8 +143,8 @@ module ActiveSupport
135
143
 
136
144
  def decrement(name, amount = 1, options = nil) # :nodoc:
137
145
  options = merged_options(options)
138
- instrument(:decrement, name, :amount => amount) do
139
- @data.decr(escape_key(namespaced_key(name, options)), amount)
146
+ instrument(:decrement, name, amount: amount) do
147
+ @data.decr(normalize_key(name, options), amount)
140
148
  end
141
149
  rescue *NONFATAL_EXCEPTIONS => e
142
150
  @data.log_exception(e)
@@ -144,14 +152,18 @@ module ActiveSupport
144
152
  end
145
153
 
146
154
  def clear(options = nil)
147
- instrument(:clear, options) { @data.flush_all }
155
+ ActiveSupport::Notifications.instrument("cache_clear.active_support", options || {}) do
156
+ @data.flush_all
157
+ end
148
158
  end
149
159
 
150
160
  def stats
151
- instrument(:stats) { @data.stats }
161
+ ActiveSupport::Notifications.instrument("cache_stats.active_support") do
162
+ @data.stats
163
+ end
152
164
  end
153
165
 
154
- def exist?(*args)
166
+ def exist?(*)
155
167
  !!super
156
168
  end
157
169
 
@@ -163,70 +175,90 @@ module ActiveSupport
163
175
  end
164
176
 
165
177
  protected
166
- def read_entry(key, options) # :nodoc:
167
- deserialize_entry(@data.get(escape_key(key), true))
168
- rescue *NONFATAL_EXCEPTIONS => e
169
- @data.log_exception(e)
170
- nil
171
- end
172
178
 
173
- def write_entry(key, entry, options) # :nodoc:
174
- return true if read_only
175
- method = options && options[:unless_exist] ? :add : :set
176
- expires_in = expiration(options)
177
- value, raw = serialize_entry(entry, options)
178
- @data.send(method, escape_key(key), value, expires_in, raw)
179
- rescue *NONFATAL_EXCEPTIONS => e
180
- @data.log_exception(e)
181
- false
182
- end
179
+ def read_entry(key, _options) # :nodoc:
180
+ deserialize_entry(@data.get(escape_key(key), true))
181
+ rescue *NONFATAL_EXCEPTIONS => e
182
+ @data.log_exception(e)
183
+ nil
184
+ end
183
185
 
184
- def delete_entry(key, options) # :nodoc:
185
- return true if read_only
186
- @data.delete(escape_key(key))
187
- true
188
- rescue *NONFATAL_EXCEPTIONS => e
189
- @data.log_exception(e)
190
- false
191
- end
186
+ def write_entry(key, entry, options) # :nodoc:
187
+ return true if read_only
188
+ method = options && options[:unless_exist] ? :add : :set
189
+ expires_in = expiration(options)
190
+ value, raw = serialize_entry(entry, options)
191
+ @data.send(method, escape_key(key), value, expires_in, raw)
192
+ rescue *NONFATAL_EXCEPTIONS => e
193
+ @data.log_exception(e)
194
+ false
195
+ end
196
+
197
+ def delete_entry(key, _options) # :nodoc:
198
+ return true if read_only
199
+ @data.delete(escape_key(key))
200
+ true
201
+ rescue *NONFATAL_EXCEPTIONS => e
202
+ @data.log_exception(e)
203
+ false
204
+ end
192
205
 
193
206
  private
194
207
 
208
+ if ActiveSupport::VERSION::MAJOR < 5
209
+ def normalize_key(key, options)
210
+ escape_key(namespaced_key(key, options))
211
+ end
212
+
195
213
  def escape_key(key)
196
214
  key = key.to_s.dup
197
215
  key = key.force_encoding(Encoding::ASCII_8BIT)
198
- key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" }
216
+ key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
199
217
  key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
200
218
  key
201
219
  end
202
-
203
- def deserialize_entry(raw_value)
204
- if raw_value
205
- entry = Marshal.load(raw_value) rescue raw_value
206
- entry.is_a?(Entry) ? entry : Entry.new(entry)
207
- else
208
- nil
209
- end
220
+ else
221
+ def normalize_key(key, options)
222
+ key = super.dup
223
+ key = key.force_encoding(Encoding::ASCII_8BIT)
224
+ key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
225
+ key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
226
+ key
210
227
  end
211
228
 
212
- def serialize_entry(entry, options)
213
- entry = entry.value.to_s if options[:raw]
214
- [entry, options[:raw]]
229
+ def escape_key(key)
230
+ key
215
231
  end
232
+ end
216
233
 
217
- def cas_raw?(options)
218
- options[:raw]
234
+ def deserialize_entry(raw_value)
235
+ if raw_value
236
+ entry = begin
237
+ Marshal.load(raw_value)
238
+ rescue
239
+ raw_value
240
+ end
241
+ entry.is_a?(Entry) ? entry : Entry.new(entry)
219
242
  end
243
+ end
220
244
 
221
- def expiration(options)
222
- expires_in = options[:expires_in].to_i
223
- if expires_in > 0 && !options[:raw]
224
- # Set the memcache expire a few minutes in the future to support race condition ttls on read
225
- expires_in += 5.minutes
226
- end
227
- expires_in
228
- end
245
+ def serialize_entry(entry, options)
246
+ entry = entry.value.to_s if options[:raw]
247
+ [entry, options[:raw]]
248
+ end
249
+
250
+ def cas_raw?(options)
251
+ options[:raw]
252
+ end
229
253
 
254
+ def expiration(options)
255
+ expires_in = options[:expires_in].to_i
256
+ if expires_in > 0 && !options[:raw]
257
+ # Set the memcache expire a few minutes in the future to support race condition ttls on read
258
+ expires_in += 5.minutes
259
+ end
260
+ expires_in
261
+ end
230
262
  end
231
263
  end
232
264
  end
@@ -1,3 +1,3 @@
1
1
  require "memcached"
2
+ require "active_support"
2
3
  require "active_support/cache"
3
- require "memcached_store/memcached_safety"
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module MemcachedStore
3
- VERSION = "0.12.8"
3
+ VERSION = "1.0.0"
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: 0.12.8
4
+ version: 1.0.0
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: 2016-11-30 00:00:00.000000000 Z
14
+ date: 2016-12-01 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: '3.2'
22
+ version: '4'
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: '3.2'
29
+ version: '4'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: memcached
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -65,25 +65,15 @@ executables: []
65
65
  extensions: []
66
66
  extra_rdoc_files: []
67
67
  files:
68
- - ".gitignore"
69
- - ".travis.yml"
70
- - Gemfile
71
68
  - LICENSE
72
69
  - README.md
73
- - Rakefile
74
70
  - lib/active_support/cache/memcached_snappy_store.rb
75
71
  - lib/active_support/cache/memcached_store.rb
76
72
  - lib/memcached_store.rb
77
- - lib/memcached_store/memcached_safety.rb
78
73
  - lib/memcached_store/version.rb
79
- - memcached_store.gemspec
80
- - shipit.rubygems.yml
81
- - test/test_helper.rb
82
- - test/test_memcached_safety.rb
83
- - test/test_memcached_snappy_store.rb
84
- - test/test_memcached_store.rb
85
74
  homepage: https://github.com/Shopify/memcached_store/
86
- licenses: []
75
+ licenses:
76
+ - MIT
87
77
  metadata: {}
88
78
  post_install_message:
89
79
  rdoc_options: []
@@ -93,7 +83,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
83
  requirements:
94
84
  - - ">="
95
85
  - !ruby/object:Gem::Version
96
- version: '0'
86
+ version: 2.2.0
97
87
  required_rubygems_version: !ruby/object:Gem::Requirement
98
88
  requirements:
99
89
  - - ">="
@@ -105,8 +95,4 @@ rubygems_version: 2.5.1
105
95
  signing_key:
106
96
  specification_version: 4
107
97
  summary: Plugin-able Memcached adapters to add features (compression, safety)
108
- test_files:
109
- - test/test_helper.rb
110
- - test/test_memcached_safety.rb
111
- - test/test_memcached_snappy_store.rb
112
- - test/test_memcached_store.rb
98
+ test_files: []