Skip to content

Commit 2f73343

Browse files
committed
Rails 7.0 support and drop older railses
1 parent fcb225a commit 2f73343

File tree

9 files changed

+88
-743
lines changed

9 files changed

+88
-743
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,10 @@ jobs:
88
strategy:
99
matrix:
1010
entry:
11-
- name: 'Minimum supported'
12-
ruby: '2.6'
13-
gemfile: "Gemfile.min"
14-
- name: 'Latest released'
15-
ruby: '3.0'
16-
gemfile: "Gemfile"
17-
- name: 'Rails edge'
18-
ruby: '3.0'
19-
gemfile: "Gemfile.edge"
11+
- ruby: '2.7'
12+
- ruby: '3.0'
2013

21-
name: ${{ matrix.entry.name }}
22-
23-
env:
24-
BUNDLE_GEMFILE: ${{ matrix.entry.gemfile }}
14+
name: "Ruby ${{ matrix.entry.ruby }}"
2515

2616
services:
2717
memcached:

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ source 'https://rubygems.org'
22

33
gemspec
44

5-
gem "snappy"
5+
gem "rails", github: "rails/rails", branch: "main"

Gemfile.min

Lines changed: 0 additions & 7 deletions
This file was deleted.

lib/active_support/cache/memcached_snappy_store.rb

Lines changed: 0 additions & 45 deletions
This file was deleted.

lib/active_support/cache/memcached_store.rb

Lines changed: 40 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -14,58 +14,21 @@ module Cache
1414
class MemcachedStore < Store
1515
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
1616

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
17+
module RawCodec
18+
def self.encode(_key, value, flags)
4219
[value, flags]
4320
end
4421

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
22+
def self.decode(_key, value, _flags)
23+
value
5724
end
5825
end
5926

60-
attr_accessor :read_only, :swallow_exceptions
61-
6227
prepend(Strategy::LocalCache)
6328

6429
def initialize(*addresses, **options)
6530
addresses = addresses.flatten
66-
options[:codec] ||= Codec.new
67-
@swallow_exceptions = true
68-
@swallow_exceptions = options.delete(:swallow_exceptions) if options.key?(:swallow_exceptions)
31+
options[:codec] ||= RawCodec
6932

7033
super(options)
7134

@@ -82,7 +45,6 @@ def initialize(*addresses, **options)
8245
end
8346

8447
def append(name, value, options = nil)
85-
return true if read_only
8648
options = merged_options(options)
8749
normalized_key = normalize_key(name, options)
8850

@@ -94,16 +56,6 @@ def append(name, value, options = nil)
9456
end
9557
end
9658

97-
def write(*)
98-
return true if read_only
99-
super
100-
end
101-
102-
def delete(*)
103-
return true if read_only
104-
super
105-
end
106-
10759
def read_multi(*names)
10860
options = names.extract_options!
10961
return {} if names.empty?
@@ -116,7 +68,7 @@ def read_multi(*names)
11668
instrument(:read_multi, names, options) do
11769
if raw_values = @connection.get(keys_to_names.keys)
11870
raw_values.each do |key, value|
119-
entry = deserialize_entry(value)
71+
entry = deserialize_entry(value, **options)
12072
values[keys_to_names[key]] = entry.value unless entry.expired?
12173
end
12274
end
@@ -134,8 +86,7 @@ def cas(name, options = nil)
13486
@connection.cas(key, expiration(options)) do |raw_value|
13587
entry = deserialize_entry(raw_value)
13688
value = yield entry.value
137-
break true if read_only
138-
serialize_entry(Entry.new(value, **options), options)
89+
serialize_entry(Entry.new(value, **options), **options)
13990
end
14091
end
14192
true
@@ -160,10 +111,8 @@ def cas_multi(*names, **options)
160111

161112
values = yield values
162113

163-
break true if read_only
164-
165114
serialized_values = values.map do |name, value|
166-
[normalize_key(name, options), serialize_entry(Entry.new(value, **options), options)]
115+
[normalize_key(name, options), serialize_entry(Entry.new(value, **options), **options)]
167116
end
168117

169118
Hash[serialized_values]
@@ -215,118 +164,61 @@ def reset #:nodoc:
215164

216165
private
217166

218-
if private_method_defined?(:read_serialized_entry)
219-
class DupLocalStore < DelegateClass(Strategy::LocalCache::LocalStore)
220-
def write_entry(_key, entry)
221-
if entry.is_a?(Entry)
222-
entry.dup_value!
223-
end
224-
super
225-
end
226-
227-
def fetch_entry(key)
228-
entry = super do
229-
new_entry = yield
230-
if entry.is_a?(Entry)
231-
new_entry.dup_value!
232-
end
233-
new_entry
234-
end
235-
entry = entry.dup
236-
237-
if entry.is_a?(Entry)
238-
entry.dup_value!
239-
end
240-
241-
entry
242-
end
243-
end
244-
245-
module DupLocalCache
246-
private
247-
248-
def local_cache
249-
if local_cache = super
250-
DupLocalStore.new(local_cache)
251-
end
252-
end
253-
end
254-
255-
prepend DupLocalCache
256-
257-
def read_entry(key, **options) # :nodoc:
258-
deserialize_entry(read_serialized_entry(key, **options))
259-
end
260-
261-
def read_serialized_entry(key, **)
262-
handle_exceptions(return_value_on_error: nil) do
263-
@connection.get(key)
264-
end
265-
end
266-
267-
def write_entry(key, entry, **options) # :nodoc:
268-
return true if read_only
167+
def read_entry(key, **options) # :nodoc:
168+
deserialize_entry(read_serialized_entry(key, **options), **options)
169+
end
269170

270-
write_serialized_entry(key, serialize_entry(entry, **options), **options)
171+
def read_serialized_entry(key, **)
172+
handle_exceptions(return_value_on_error: nil) do
173+
@connection.get(key)
271174
end
175+
end
272176

273-
def write_serialized_entry(key, value, **options)
274-
method = options && options[:unless_exist] ? :add : :set
275-
expires_in = expiration(options)
276-
handle_exceptions(return_value_on_error: false) do
277-
@connection.send(method, key, value, expires_in)
278-
true
279-
end
280-
end
281-
else
282-
def read_entry(key, _options) # :nodoc:
283-
handle_exceptions(return_value_on_error: nil) do
284-
deserialize_entry(@connection.get(key))
285-
end
286-
end
177+
def write_entry(key, entry, **options) # :nodoc:
178+
write_serialized_entry(key, serialize_entry(entry, **options), **options)
179+
end
287180

288-
def write_entry(key, entry, options) # :nodoc:
289-
return true if read_only
290-
method = options && options[:unless_exist] ? :add : :set
291-
expires_in = expiration(options)
292-
value = serialize_entry(entry, options)
293-
handle_exceptions(return_value_on_error: false) do
294-
@connection.send(method, key, value, expires_in)
295-
true
296-
end
181+
def write_serialized_entry(key, value, **options)
182+
method = options && options[:unless_exist] ? :add : :set
183+
expires_in = expiration(options)
184+
handle_exceptions(return_value_on_error: false) do
185+
@connection.send(method, key, value, expires_in)
186+
true
297187
end
298188
end
299189

300190
def delete_entry(key, _options) # :nodoc:
301-
return true if read_only
302191
handle_exceptions(return_value_on_error: false, on_miss: true) do
303192
@connection.delete(key)
304193
true
305194
end
306195
end
307196

308-
private
309-
310197
def normalize_key(key, options)
311198
key = super.dup
312199
key = key.force_encoding(Encoding::ASCII_8BIT)
313200
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
314-
# When we remove support to Rails 5.1 we can change the code to use ActiveSupport::Digest
315201
key = "#{key[0, 213]}:md5:#{::Digest::MD5.hexdigest(key)}" if key.size > 250
316202
key
317203
end
318204

319-
def deserialize_entry(value)
320-
unless value.nil?
321-
value.is_a?(Entry) ? value : Entry.new(value, compress: false)
205+
def deserialize_entry(payload, raw: false, **)
206+
if !payload.nil? && raw
207+
if payload.is_a?(Entry)
208+
payload
209+
else
210+
Entry.new(payload, compress: false)
211+
end
212+
else
213+
super(payload)
322214
end
323215
end
324216

325-
def serialize_entry(entry, options)
326-
if options[:raw]
217+
def serialize_entry(entry, raw: false, **)
218+
if raw
327219
entry.value.to_s
328220
else
329-
entry
221+
super(entry)
330222
end
331223
end
332224

@@ -342,19 +234,16 @@ def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error, mi
342234
yield
343235
rescue Memcached::NotFound, Memcached::ConnectionDataExists, *miss_exceptions
344236
on_miss
237+
rescue Memcached::NotStored
238+
return_value_on_error
345239
rescue Memcached::Error => e
346240
log_warning(e)
347-
raise unless @swallow_exceptions
348241
return_value_on_error
349242
end
350243

351244
def log_warning(err)
352-
return unless logger
353-
return if err.is_a?(Memcached::NotStored) && @swallow_exceptions
354-
355-
logger.warn(
356-
"[MEMCACHED_ERROR] swallowed=#{@swallow_exceptions}" \
357-
" exception_class=#{err.class} exception_message=#{err.message}"
245+
logger&.warn(
246+
"[MEMCACHED_ERROR] exception_class=#{err.class} exception_message=#{err.message}"
358247
)
359248
end
360249

memcached_store.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ Gem::Specification.new do |spec|
1717
spec.files = Dir["lib/**/*.rb", "README.md", "LICENSE"]
1818
spec.require_paths = ["lib"]
1919

20-
spec.required_ruby_version = ">= 2.6.0"
20+
spec.required_ruby_version = ">= 2.7.0"
2121

22-
spec.add_runtime_dependency "activesupport", ">= 6"
22+
spec.add_runtime_dependency "activesupport", ">= 7.0.0.alpha"
2323
spec.add_runtime_dependency "memcached", "~> 1.8"
2424

2525
spec.add_development_dependency "rake"

0 commit comments

Comments
 (0)