dalli 2.7.11 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dalli might be problematic. Click here for more details.

metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dalli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.11
4
+ version: 3.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter M. Goldstein
@@ -9,8 +9,92 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-09-26 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2021-11-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: connection_pool
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rack
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rubocop
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rubocop-minitest
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop-performance
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop-rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
14
98
  description: High performance memcached client for Ruby
15
99
  email:
16
100
  - peter.m.goldstein@gmail.com
@@ -23,23 +107,33 @@ files:
23
107
  - History.md
24
108
  - LICENSE
25
109
  - README.md
26
- - lib/action_dispatch/middleware/session/dalli_store.rb
27
- - lib/active_support/cache/dalli_store.rb
28
110
  - lib/dalli.rb
29
111
  - lib/dalli/cas/client.rb
30
112
  - lib/dalli/client.rb
31
113
  - lib/dalli/compressor.rb
114
+ - lib/dalli/key_manager.rb
32
115
  - lib/dalli/options.rb
33
- - lib/dalli/railtie.rb
116
+ - lib/dalli/protocol.rb
117
+ - lib/dalli/protocol/binary.rb
118
+ - lib/dalli/protocol/binary/request_formatter.rb
119
+ - lib/dalli/protocol/binary/response_processor.rb
120
+ - lib/dalli/protocol/binary/sasl_authentication.rb
121
+ - lib/dalli/protocol/server_config_parser.rb
122
+ - lib/dalli/protocol/ttl_sanitizer.rb
123
+ - lib/dalli/protocol/value_compressor.rb
124
+ - lib/dalli/protocol/value_marshaller.rb
125
+ - lib/dalli/protocol/value_serializer.rb
34
126
  - lib/dalli/ring.rb
35
127
  - lib/dalli/server.rb
128
+ - lib/dalli/servers_arg_normalizer.rb
36
129
  - lib/dalli/socket.rb
37
130
  - lib/dalli/version.rb
38
131
  - lib/rack/session/dalli.rb
39
132
  homepage: https://github.com/petergoldstein/dalli
40
133
  licenses:
41
134
  - MIT
42
- metadata: {}
135
+ metadata:
136
+ rubygems_mfa_required: 'true'
43
137
  post_install_message:
44
138
  rdoc_options: []
45
139
  require_paths:
@@ -48,15 +142,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
48
142
  requirements:
49
143
  - - ">="
50
144
  - !ruby/object:Gem::Version
51
- version: '0'
145
+ version: '2.5'
52
146
  required_rubygems_version: !ruby/object:Gem::Requirement
53
147
  requirements:
54
148
  - - ">="
55
149
  - !ruby/object:Gem::Version
56
150
  version: '0'
57
151
  requirements: []
58
- rubyforge_project:
59
- rubygems_version: 2.7.6.2
152
+ rubygems_version: 3.2.31
60
153
  signing_key:
61
154
  specification_version: 4
62
155
  summary: High performance memcached client for Ruby
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'active_support/cache'
3
- require 'action_dispatch/middleware/session/abstract_store'
4
- require 'dalli'
5
-
6
- # Dalli-based session store for Rails 3.0.
7
- module ActionDispatch
8
- module Session
9
- class DalliStore < AbstractStore
10
- def initialize(app, options = {})
11
- # Support old :expires option
12
- options[:expire_after] ||= options[:expires]
13
-
14
- super
15
-
16
- @default_options = { :namespace => 'rack:session' }.merge(@default_options)
17
-
18
- @pool = options[:cache] || begin
19
- Dalli::Client.new(
20
- @default_options[:memcache_server], @default_options)
21
- end
22
- @namespace = @default_options[:namespace]
23
-
24
- @raise_errors = !!@default_options[:raise_errors]
25
-
26
- super
27
- end
28
-
29
- def reset
30
- @pool.reset
31
- end
32
-
33
- private
34
-
35
- def get_session(env, sid)
36
- sid = generate_sid unless sid and !sid.empty?
37
- begin
38
- session = @pool.get(sid) || {}
39
- rescue Dalli::DalliError => ex
40
- # re-raise ArgumentError so Rails' session abstract_store.rb can autoload any missing models
41
- raise ArgumentError, ex.message if ex.message =~ /unmarshal/
42
- Rails.logger.warn("Session::DalliStore#get: #{ex.message}")
43
- session = {}
44
- end
45
- [sid, session]
46
- end
47
-
48
- def set_session(env, sid, session_data, options = nil)
49
- options ||= env[ENV_SESSION_OPTIONS_KEY]
50
- expiry = options[:expire_after]
51
- @pool.set(sid, session_data, expiry)
52
- sid
53
- rescue Dalli::DalliError
54
- Rails.logger.warn("Session::DalliStore#set: #{$!.message}")
55
- raise if @raise_errors
56
- false
57
- end
58
-
59
- def destroy_session(env, session_id, options)
60
- begin
61
- @pool.delete(session_id)
62
- rescue Dalli::DalliError
63
- Rails.logger.warn("Session::DalliStore#destroy_session: #{$!.message}")
64
- raise if @raise_errors
65
- end
66
- return nil if options[:drop]
67
- generate_sid
68
- end
69
-
70
- def destroy(env)
71
- if sid = current_session_id(env)
72
- @pool.delete(sid)
73
- end
74
- rescue Dalli::DalliError
75
- Rails.logger.warn("Session::DalliStore#destroy: #{$!.message}")
76
- raise if @raise_errors
77
- false
78
- end
79
-
80
- end
81
- end
82
- end
@@ -1,441 +0,0 @@
1
- # encoding: ascii
2
- # frozen_string_literal: true
3
- require 'dalli'
4
-
5
- module ActiveSupport
6
- module Cache
7
- class DalliStore
8
-
9
- attr_reader :silence, :options
10
- alias_method :silence?, :silence
11
-
12
- def self.supports_cache_versioning?
13
- true
14
- end
15
-
16
- # Silence the logger.
17
- def silence!
18
- @silence = true
19
- self
20
- end
21
-
22
- # Silence the logger within a block.
23
- def mute
24
- previous_silence, @silence = defined?(@silence) && @silence, true
25
- yield
26
- ensure
27
- @silence = previous_silence
28
- end
29
-
30
- ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/
31
-
32
- # Creates a new DalliStore object, with the given memcached server
33
- # addresses. Each address is either a host name, or a host-with-port string
34
- # in the form of "host_name:port". For example:
35
- #
36
- # ActiveSupport::Cache::DalliStore.new("localhost", "server-downstairs.localnetwork:8229")
37
- #
38
- # If no addresses are specified, then DalliStore will connect to
39
- # localhost port 11211 (the default memcached port).
40
- #
41
- # Connection Pool support
42
- #
43
- # If you are using multithreaded Rails, the Rails.cache singleton can become a source
44
- # of contention. You can use a connection pool of Dalli clients with Rails.cache by
45
- # passing :pool_size and/or :pool_timeout:
46
- #
47
- # config.cache_store = :dalli_store, 'localhost:11211', :pool_size => 10
48
- #
49
- # Both pool options default to 5. You must include the `connection_pool` gem if you
50
- # wish to use pool support.
51
- #
52
- def initialize(*addresses)
53
- puts <<-EOS
54
- DEPRECATION: :dalli_store will be removed in Dalli 3.0.
55
- Please use Rails' official :mem_cache_store instead.
56
- https://guides.rubyonrails.org/caching_with_rails.html
57
- EOS
58
- addresses = addresses.flatten
59
- options = addresses.extract_options!
60
- @options = options.dup
61
-
62
- pool_options = {}
63
- pool_options[:size] = options[:pool_size] if options[:pool_size]
64
- pool_options[:timeout] = options[:pool_timeout] if options[:pool_timeout]
65
-
66
- @options[:compress] ||= @options[:compression]
67
-
68
- addresses.compact!
69
- servers = if addresses.empty?
70
- nil # use the default from Dalli::Client
71
- else
72
- addresses
73
- end
74
- if pool_options.empty?
75
- @data = Dalli::Client.new(servers, @options)
76
- else
77
- @data = ::ConnectionPool.new(pool_options) { Dalli::Client.new(servers, @options.merge(:threadsafe => false)) }
78
- end
79
-
80
- extend Strategy::LocalCache
81
- extend LocalCacheEntryUnwrapAndRaw
82
- end
83
-
84
- ##
85
- # Access the underlying Dalli::Client or ConnectionPool instance for
86
- # access to get_multi, etc.
87
- def dalli
88
- @data
89
- end
90
-
91
- def with(&block)
92
- @data.with(&block)
93
- end
94
-
95
- # Fetch the value associated with the key.
96
- # If a value is found, then it is returned.
97
- #
98
- # If a value is not found and no block is given, then nil is returned.
99
- #
100
- # If a value is not found (or if the found value is nil and :cache_nils is false)
101
- # and a block is given, the block will be invoked and its return value
102
- # written to the cache and returned.
103
- def fetch(name, options=nil)
104
- options ||= {}
105
- options[:cache_nils] = true if @options[:cache_nils]
106
- namespaced_name = namespaced_key(name, options)
107
- not_found = options[:cache_nils] ? Dalli::Server::NOT_FOUND : nil
108
- if block_given?
109
- entry = not_found
110
- unless options[:force]
111
- entry = instrument_with_log(:read, namespaced_name, options) do |payload|
112
- read_entry(namespaced_name, options).tap do |result|
113
- if payload
114
- payload[:super_operation] = :fetch
115
- payload[:hit] = not_found != result
116
- end
117
- end
118
- end
119
- end
120
-
121
- if not_found == entry
122
- result = instrument_with_log(:generate, namespaced_name, options) do |payload|
123
- yield(name)
124
- end
125
- write(name, result, options)
126
- result
127
- else
128
- instrument_with_log(:fetch_hit, namespaced_name, options) { |payload| }
129
- entry
130
- end
131
- else
132
- read(name, options)
133
- end
134
- end
135
-
136
- def read(name, options=nil)
137
- options ||= {}
138
- name = namespaced_key(name, options)
139
-
140
- instrument_with_log(:read, name, options) do |payload|
141
- entry = read_entry(name, options)
142
- payload[:hit] = !entry.nil? if payload
143
- entry
144
- end
145
- end
146
-
147
- def write(name, value, options=nil)
148
- options ||= {}
149
- name = namespaced_key(name, options)
150
-
151
- instrument_with_log(:write, name, options) do |payload|
152
- with do |connection|
153
- options = options.merge(:connection => connection)
154
- write_entry(name, value, options)
155
- end
156
- end
157
- end
158
-
159
- def exist?(name, options=nil)
160
- options ||= {}
161
- name = namespaced_key(name, options)
162
-
163
- log(:exist, name, options)
164
- !read_entry(name, options).nil?
165
- end
166
-
167
- def delete(name, options=nil)
168
- options ||= {}
169
- name = namespaced_key(name, options)
170
-
171
- instrument_with_log(:delete, name, options) do |payload|
172
- delete_entry(name, options)
173
- end
174
- end
175
-
176
- # Reads multiple keys from the cache using a single call to the
177
- # servers for all keys. Keys must be Strings.
178
- def read_multi(*names)
179
- options = names.extract_options!
180
- mapping = names.inject({}) { |memo, name| memo[namespaced_key(name, options)] = name; memo }
181
- instrument_with_log(:read_multi, mapping.keys) do
182
- results = {}
183
- if local_cache
184
- mapping.each_key do |key|
185
- if value = local_cache.read_entry(key, options)
186
- results[key] = value
187
- end
188
- end
189
- end
190
-
191
- data = with { |c| c.get_multi(mapping.keys - results.keys) }
192
- results.merge!(data)
193
- results.inject({}) do |memo, (inner, _)|
194
- entry = results[inner]
195
- # NB Backwards data compatibility, to be removed at some point
196
- value = (entry.is_a?(ActiveSupport::Cache::Entry) ? entry.value : entry)
197
- memo[mapping[inner]] = value
198
- local_cache.write_entry(inner, value, options) if local_cache
199
- memo
200
- end
201
- end
202
- end
203
-
204
- # Fetches data from the cache, using the given keys. If there is data in
205
- # the cache with the given keys, then that data is returned. Otherwise,
206
- # the supplied block is called for each key for which there was no data,
207
- # and the result will be written to the cache and returned.
208
- def fetch_multi(*names)
209
- options = names.extract_options!
210
- mapping = names.inject({}) { |memo, name| memo[namespaced_key(name, options)] = name; memo }
211
-
212
- instrument_with_log(:fetch_multi, mapping.keys) do
213
- with do |connection|
214
- results = connection.get_multi(mapping.keys)
215
-
216
- connection.multi do
217
- mapping.inject({}) do |memo, (expanded, name)|
218
- memo[name] = results[expanded]
219
- if memo[name].nil?
220
- value = yield(name)
221
- memo[name] = value
222
- options = options.merge(:connection => connection)
223
- write_entry(expanded, value, options)
224
- end
225
-
226
- memo
227
- end
228
- end
229
- end
230
- end
231
- end
232
-
233
- # Increment a cached value. This method uses the memcached incr atomic
234
- # operator and can only be used on values written with the :raw option.
235
- # Calling it on a value not stored with :raw will fail.
236
- # :initial defaults to the amount passed in, as if the counter was initially zero.
237
- # memcached counters cannot hold negative values.
238
- def increment(name, amount = 1, options=nil)
239
- options ||= {}
240
- name = namespaced_key(name, options)
241
- initial = options.has_key?(:initial) ? options[:initial] : amount
242
- expires_in = options[:expires_in]
243
- instrument_with_log(:increment, name, :amount => amount) do
244
- with { |c| c.incr(name, amount, expires_in, initial) }
245
- end
246
- rescue Dalli::DalliError => e
247
- log_dalli_error(e)
248
- instrument_error(e) if instrument_errors?
249
- raise if raise_errors?
250
- nil
251
- end
252
-
253
- # Decrement a cached value. This method uses the memcached decr atomic
254
- # operator and can only be used on values written with the :raw option.
255
- # Calling it on a value not stored with :raw will fail.
256
- # :initial defaults to zero, as if the counter was initially zero.
257
- # memcached counters cannot hold negative values.
258
- def decrement(name, amount = 1, options=nil)
259
- options ||= {}
260
- name = namespaced_key(name, options)
261
- initial = options.has_key?(:initial) ? options[:initial] : 0
262
- expires_in = options[:expires_in]
263
- instrument_with_log(:decrement, name, :amount => amount) do
264
- with { |c| c.decr(name, amount, expires_in, initial) }
265
- end
266
- rescue Dalli::DalliError => e
267
- log_dalli_error(e)
268
- instrument_error(e) if instrument_errors?
269
- raise if raise_errors?
270
- nil
271
- end
272
-
273
- # Clear the entire cache on all memcached servers. This method should
274
- # be used with care when using a shared cache.
275
- def clear(options=nil)
276
- instrument_with_log(:clear, 'flushing all keys') do
277
- with { |c| c.flush_all }
278
- end
279
- rescue Dalli::DalliError => e
280
- log_dalli_error(e)
281
- instrument_error(e) if instrument_errors?
282
- raise if raise_errors?
283
- nil
284
- end
285
-
286
- # Clear any local cache
287
- def cleanup(options=nil)
288
- end
289
-
290
- # Get the statistics from the memcached servers.
291
- def stats
292
- with { |c| c.stats }
293
- end
294
-
295
- def reset
296
- with { |c| c.reset }
297
- end
298
-
299
- def logger
300
- Dalli.logger
301
- end
302
-
303
- def logger=(new_logger)
304
- Dalli.logger = new_logger
305
- end
306
-
307
- protected
308
-
309
- # Read an entry from the cache.
310
- def read_entry(key, options) # :nodoc:
311
- entry = with { |c| c.get(key, options) }
312
- # NB Backwards data compatibility, to be removed at some point
313
- entry.is_a?(ActiveSupport::Cache::Entry) ? entry.value : entry
314
- rescue Dalli::DalliError => e
315
- log_dalli_error(e)
316
- instrument_error(e) if instrument_errors?
317
- raise if raise_errors?
318
- nil
319
- end
320
-
321
- # Write an entry to the cache.
322
- def write_entry(key, value, options) # :nodoc:
323
- # cleanup LocalCache
324
- cleanup if options[:unless_exist]
325
- method = options[:unless_exist] ? :add : :set
326
- expires_in = options[:expires_in]
327
- connection = options.delete(:connection)
328
- connection.send(method, key, value, expires_in, options)
329
- rescue Dalli::DalliError => e
330
- log_dalli_error(e)
331
- instrument_error(e) if instrument_errors?
332
- raise if raise_errors?
333
- false
334
- end
335
-
336
- # Delete an entry from the cache.
337
- def delete_entry(key, options) # :nodoc:
338
- with { |c| c.delete(key) }
339
- rescue Dalli::DalliError => e
340
- log_dalli_error(e)
341
- instrument_error(e) if instrument_errors?
342
- raise if raise_errors?
343
- false
344
- end
345
-
346
- private
347
-
348
- def namespaced_key(key, options)
349
- digest_class = @options[:digest_class] || ::Digest::MD5
350
- key = expanded_key(key)
351
- namespace = options[:namespace] if options
352
- prefix = namespace.is_a?(Proc) ? namespace.call : namespace
353
- key = "#{prefix}:#{key}" if prefix
354
- key = "#{key[0, 213]}:md5:#{digest_class.hexdigest(key)}" if key && key.size > 250
355
- key
356
- end
357
- alias :normalize_key :namespaced_key
358
-
359
- # Expand key to be a consistent string value. Invokes +cache_key_with_version+
360
- # first to support Rails 5.2 cache versioning.
361
- # Invoke +cache_key+ if object responds to +cache_key+. Otherwise, to_param method
362
- # will be called. If the key is a Hash, then keys will be sorted alphabetically.
363
- def expanded_key(key) # :nodoc:
364
- return key.cache_key_with_version.to_s if key.respond_to?(:cache_key_with_version)
365
- return key.cache_key.to_s if key.respond_to?(:cache_key)
366
-
367
- case key
368
- when Array
369
- if key.size > 1
370
- key = key.collect{|element| expanded_key(element)}
371
- else
372
- key = key.first
373
- end
374
- when Hash
375
- key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
376
- end
377
-
378
- key = key.to_param
379
- if key.respond_to? :force_encoding
380
- key = key.dup
381
- key.force_encoding('binary')
382
- end
383
- key
384
- end
385
-
386
- def log_dalli_error(error)
387
- logger.error("DalliError: #{error.message}") if logger
388
- end
389
-
390
- def instrument_with_log(operation, key, options=nil)
391
- log(operation, key, options)
392
-
393
- payload = { :key => key }
394
- payload.merge!(options) if options.is_a?(Hash)
395
- instrument(operation, payload) { |p| yield(p) }
396
- end
397
-
398
- def instrument_error(error)
399
- instrument(:error, { :key => 'DalliError', :message => error.message })
400
- end
401
-
402
- def instrument(operation, payload)
403
- ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload) do
404
- yield(payload) if block_given?
405
- end
406
- end
407
-
408
- def log(operation, key, options=nil)
409
- return unless logger && logger.debug? && !silence?
410
- logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
411
- end
412
-
413
- def raise_errors?
414
- !!@options[:raise_errors]
415
- end
416
-
417
- def instrument_errors?
418
- !!@options[:instrument_errors]
419
- end
420
-
421
- # Make sure LocalCache is giving raw values, not `Entry`s, and
422
- # respect `raw` option.
423
- module LocalCacheEntryUnwrapAndRaw # :nodoc:
424
- protected
425
- def read_entry(key, options)
426
- retval = super(key, **options)
427
- if retval.is_a? ActiveSupport::Cache::Entry
428
- # Must have come from LocalStore, unwrap it
429
- if options[:raw]
430
- retval.value.to_s
431
- else
432
- retval.value
433
- end
434
- else
435
- retval
436
- end
437
- end
438
- end
439
- end
440
- end
441
- end
data/lib/dalli/railtie.rb DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
- module Dalli
3
- class Railtie < ::Rails::Railtie
4
- config.before_configuration do
5
- config.cache_store = :dalli_store
6
- end
7
- end
8
- end