Skip to content

Commit 1a157d5

Browse files
committed
Rails 7.0 support and drop older railses
1 parent 7fc92be commit 1a157d5

File tree

10 files changed

+296
-657
lines changed

10 files changed

+296
-657
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +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"
11+
- ruby: '2.7'
12+
- ruby: '3.0'
1713

18-
name: ${{ matrix.entry.name }}
19-
20-
env:
21-
BUNDLE_GEMFILE: ${{ matrix.entry.gemfile }}
14+
name: "Ruby ${{ matrix.entry.ruby }}"
2215

2316
services:
2417
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: 37 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -13,58 +13,23 @@ module Cache
1313
class MemcachedStore < Store
1414
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
1515

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
16+
attr_accessor :swallow_exceptions
3017

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
18+
module RawCodec
19+
def self.encode(_key, value, flags)
4120
[value, flags]
4221
end
4322

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
23+
def self.decode(_key, value, _flags)
24+
value
5625
end
5726
end
5827

59-
attr_accessor :read_only, :swallow_exceptions
60-
6128
prepend(Strategy::LocalCache)
6229

6330
def initialize(*addresses, **options)
6431
addresses = addresses.flatten
65-
options[:codec] ||= Codec.new
66-
@swallow_exceptions = true
67-
@swallow_exceptions = options.delete(:swallow_exceptions) if options.key?(:swallow_exceptions)
32+
options[:codec] ||= RawCodec
6833

6934
super(options)
7035

@@ -81,7 +46,6 @@ def initialize(*addresses, **options)
8146
end
8247

8348
def append(name, value, options = nil)
84-
return true if read_only
8549
options = merged_options(options)
8650
normalized_key = normalize_key(name, options)
8751

@@ -93,16 +57,6 @@ def append(name, value, options = nil)
9357
end
9458
end
9559

96-
def write(*)
97-
return true if read_only
98-
super
99-
end
100-
101-
def delete(*)
102-
return true if read_only
103-
super
104-
end
105-
10660
def read_multi(*names)
10761
options = names.extract_options!
10862
return {} if names.empty?
@@ -115,7 +69,7 @@ def read_multi(*names)
11569
instrument(:read_multi, names, options) do
11670
if raw_values = @connection.get(keys_to_names.keys)
11771
raw_values.each do |key, value|
118-
entry = deserialize_entry(value)
72+
entry = deserialize_entry(value, **options)
11973
values[keys_to_names[key]] = entry.value unless entry.expired?
12074
end
12175
end
@@ -133,8 +87,7 @@ def cas(name, options = nil)
13387
@connection.cas(key, expiration(options)) do |raw_value|
13488
entry = deserialize_entry(raw_value)
13589
value = yield entry.value
136-
break true if read_only
137-
serialize_entry(Entry.new(value, **options), options)
90+
serialize_entry(Entry.new(value, **options), **options)
13891
end
13992
end
14093
true
@@ -159,10 +112,8 @@ def cas_multi(*names, **options)
159112

160113
values = yield values
161114

162-
break true if read_only
163-
164115
serialized_values = values.map do |name, value|
165-
[normalize_key(name, options), serialize_entry(Entry.new(value, **options), options)]
116+
[normalize_key(name, options), serialize_entry(Entry.new(value, **options), **options)]
166117
end
167118

168119
Hash[serialized_values]
@@ -212,55 +163,63 @@ def reset #:nodoc:
212163
end
213164
end
214165

215-
protected
166+
private
167+
168+
def read_entry(key, **options) # :nodoc:
169+
deserialize_entry(read_serialized_entry(key, **options), **options)
170+
end
216171

217-
def read_entry(key, _options) # :nodoc:
172+
def read_serialized_entry(key, **)
218173
handle_exceptions(return_value_on_error: nil) do
219-
deserialize_entry(@connection.get(key))
174+
@connection.get(key)
220175
end
221176
end
222177

223-
def write_entry(key, entry, options) # :nodoc:
224-
return true if read_only
178+
def write_entry(key, entry, **options) # :nodoc:
179+
write_serialized_entry(key, serialize_entry(entry, **options), **options)
180+
end
181+
182+
def write_serialized_entry(key, value, **options)
225183
method = options && options[:unless_exist] ? :add : :set
226184
expires_in = expiration(options)
227-
value = serialize_entry(entry, options)
228185
handle_exceptions(return_value_on_error: false) do
229186
@connection.send(method, key, value, expires_in)
230187
true
231188
end
232189
end
233190

234191
def delete_entry(key, _options) # :nodoc:
235-
return true if read_only
236192
handle_exceptions(return_value_on_error: false, on_miss: true) do
237193
@connection.delete(key)
238194
true
239195
end
240196
end
241197

242-
private
243-
244198
def normalize_key(key, options)
245199
key = super.dup
246200
key = key.force_encoding(Encoding::ASCII_8BIT)
247201
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
248-
# When we remove support to Rails 5.1 we can change the code to use ActiveSupport::Digest
249202
key = "#{key[0, 213]}:md5:#{::Digest::MD5.hexdigest(key)}" if key.size > 250
250203
key
251204
end
252205

253-
def deserialize_entry(value)
254-
unless value.nil?
255-
value.is_a?(Entry) ? value : Entry.new(value, compress: false)
206+
def deserialize_entry(payload, raw: false, **)
207+
if !payload.nil? && raw
208+
if payload.is_a?(Entry)
209+
payload
210+
else
211+
Entry.new(payload, compress: false)
212+
end
213+
else
214+
super(payload)
256215
end
257216
end
258217

259-
def serialize_entry(entry, options)
260-
if options[:raw]
218+
def serialize_entry(entry, raw: false, **)
219+
if raw
261220
entry.value.to_s
262221
else
263-
entry
222+
super(entry)
264223
end
265224
end
266225

@@ -276,19 +235,16 @@ def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error, mi
276235
yield
277236
rescue Memcached::NotFound, Memcached::ConnectionDataExists, *miss_exceptions
278237
on_miss
238+
rescue Memcached::NotStored
239+
return_value_on_error
279240
rescue Memcached::Error => e
280241
log_warning(e)
281-
raise unless @swallow_exceptions
282242
return_value_on_error
283243
end
284244

285245
def log_warning(err)
286-
return unless logger
287-
return if err.is_a?(Memcached::NotStored) && @swallow_exceptions
288-
289-
logger.warn(
290-
"[MEMCACHED_ERROR] swallowed=#{@swallow_exceptions}" \
291-
" exception_class=#{err.class} exception_message=#{err.message}"
246+
logger&.warn(
247+
"[MEMCACHED_ERROR] exception_class=#{err.class} exception_message=#{err.message}"
292248
)
293249
end
294250

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)