dalli 5.0.3 → 5.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e67adaead94f1a41b7ef5554434e3d88742bdf6f80d6c6a7a8552ce325e4e212
4
- data.tar.gz: 51924b636e902895274ef517305e501a79c3480a440f0be83110eb17a7c88c25
3
+ metadata.gz: b211a810c4d54d2d4d92203b390e8b29260f725e6dae699ca04703ac42cef8e9
4
+ data.tar.gz: 4d765c4491412ad4b9c8ab6038232436cae5824db2abaffc20119f2dfb7fa1ee
5
5
  SHA512:
6
- metadata.gz: b36ce658adf751963219ac3a32b14680a19fdc029be2dfc575429d17e5efd6ef2dbf377610b3f3d05dc5a13824c4bb5df8477b94973e5d210f887743f6e3886a
7
- data.tar.gz: db34b04265de2c8911aae1ce20618e01375b08d769b81d965fca64e3ddd2c358b8a69ed885a821de46fe9d46d4a8f83c98f60f776a52fe8443c28ca631cfa9c6
6
+ metadata.gz: a09168f456e5ce4691d0e24b128997c3f87bee7e046592a600490bc8e9526d1ce681d156fc9997c7045e623017ee0df1273d46c16656820b0f4933b8acc42cbb
7
+ data.tar.gz: 14e72c85d60582e03b19f04b4fd822a2e789fc6f780ae3f55944271dc25f0eeb7d6de0acade39bedf4729710731d273f8501f2078dc690fa3093926041b8d178
data/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ Dalli Changelog
4
4
  Unreleased
5
5
  ==========
6
6
 
7
+ 5.0.4
8
+ ==========
9
+
10
+ Bug fixes:
11
+
12
+ - Fix `string_fastpath` flag collision with compression (#1099)
13
+ - `ValueSerializer::FLAG_UTF8` and `ValueCompressor::FLAG_COMPRESSED` were both `0x2`, causing `Dalli::UnmarshalError` on any UTF-8 string written with `string_fastpath: true` when compression is enabled, and silent encoding corruption for binary strings
14
+ - Introduces `Dalli::Flags` to centralise bit flag constants; UTF8 is reassigned to `0x4`
15
+ - Adds regression test covering short/long UTF-8, binary, and cross-client read scenarios
16
+ - Thanks to Jean Boussier and Mikael Henriksson for the fix and regression test
17
+
18
+ - Fix client-level `string_fastpath: true` being silently ignored (#1101)
19
+ - `Dalli::Client.new(servers, string_fastpath: true)` had no effect; the fast path was only taken when `string_fastpath: true` was passed as a per-request option on each `set` call
20
+ - Per-request option continues to take precedence over the client-level setting in both directions
21
+
7
22
  5.0.3
8
23
  ==========
9
24
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dalli
4
+ module Flags
5
+ # https://www.hjp.at/zettel/m/memcached_flags.rxml
6
+ # Looks like most clients use bit 0 to indicate native language serialization
7
+ SERIALIZED = 0x1
8
+
9
+ # https://www.hjp.at/zettel/m/memcached_flags.rxml
10
+ # Looks like most clients use bit 1 to indicate gzip compression.
11
+ COMPRESSED = 0x2
12
+
13
+ UTF8 = 0x4
14
+ end
15
+ end
@@ -20,10 +20,6 @@ module Dalli
20
20
 
21
21
  OPTIONS = DEFAULTS.keys.freeze
22
22
 
23
- # https://www.hjp.at/zettel/m/memcached_flags.rxml
24
- # Looks like most clients use bit 1 to indicate gzip compression.
25
- FLAG_COMPRESSED = 0x2
26
-
27
23
  def initialize(client_options)
28
24
  @compression_options =
29
25
  DEFAULTS.merge(client_options.slice(*OPTIONS))
@@ -32,13 +28,13 @@ module Dalli
32
28
  def store(value, req_options, bitflags)
33
29
  do_compress = compress_value?(value, req_options)
34
30
  store_value = do_compress ? compressor.compress(value) : value
35
- bitflags |= FLAG_COMPRESSED if do_compress
31
+ bitflags |= Flags::COMPRESSED if do_compress
36
32
 
37
33
  [store_value, bitflags]
38
34
  end
39
35
 
40
36
  def retrieve(value, bitflags)
41
- compressed = bitflags.anybits?(FLAG_COMPRESSED)
37
+ compressed = bitflags.anybits?(Flags::COMPRESSED)
42
38
  compressed ? compressor.decompress(value) : value
43
39
 
44
40
  # TODO: We likely want to move this rescue into the Dalli::Compressor / Dalli::GzipCompressor
@@ -10,16 +10,12 @@ module Dalli
10
10
  ##
11
11
  class ValueSerializer
12
12
  DEFAULTS = {
13
- serializer: Marshal
13
+ serializer: Marshal,
14
+ string_fastpath: false
14
15
  }.freeze
15
16
 
16
17
  OPTIONS = DEFAULTS.keys.freeze
17
18
 
18
- # https://www.hjp.at/zettel/m/memcached_flags.rxml
19
- # Looks like most clients use bit 0 to indicate native language serialization
20
- FLAG_SERIALIZED = 0x1
21
- FLAG_UTF8 = 0x2
22
-
23
19
  # Class variable to track whether the Marshal warning has been logged
24
20
  @@marshal_warning_logged = false # rubocop:disable Style/ClassVars
25
21
 
@@ -35,18 +31,18 @@ module Dalli
35
31
  return store_raw(value, bitflags) if req_options&.dig(:raw)
36
32
  return store_string_fastpath(value, bitflags) if use_string_fastpath?(value, req_options)
37
33
 
38
- [serialize_value(value), bitflags | FLAG_SERIALIZED]
34
+ [serialize_value(value), bitflags | Flags::SERIALIZED]
39
35
  end
40
36
 
41
37
  def retrieve(value, bitflags)
42
- serialized = bitflags.anybits?(FLAG_SERIALIZED)
38
+ serialized = bitflags.anybits?(Flags::SERIALIZED)
43
39
  if serialized
44
40
  begin
45
41
  serializer.load(value)
46
42
  rescue StandardError
47
43
  raise UnmarshalError, 'Unable to unmarshal value'
48
44
  end
49
- elsif bitflags.anybits?(FLAG_UTF8)
45
+ elsif bitflags.anybits?(Flags::UTF8)
50
46
  value.force_encoding(Encoding::UTF_8)
51
47
  else
52
48
  value
@@ -86,13 +82,15 @@ module Dalli
86
82
  def store_string_fastpath(value, bitflags)
87
83
  case value.encoding
88
84
  when Encoding::BINARY then [value, bitflags]
89
- when Encoding::UTF_8 then [value, bitflags | FLAG_UTF8]
90
- else [serialize_value(value), bitflags | FLAG_SERIALIZED]
85
+ when Encoding::UTF_8 then [value, bitflags | Flags::UTF8]
86
+ else [serialize_value(value), bitflags | Flags::SERIALIZED]
91
87
  end
92
88
  end
93
89
 
94
90
  def use_string_fastpath?(value, req_options)
95
- req_options&.dig(:string_fastpath) && value.instance_of?(String)
91
+ fastpath = req_options&.dig(:string_fastpath)
92
+ fastpath = @serialization_options[:string_fastpath] if fastpath.nil?
93
+ fastpath && value.instance_of?(String)
96
94
  end
97
95
 
98
96
  def warn_if_marshal_default(protocol_options)
data/lib/dalli/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dalli
4
- VERSION = '5.0.3'
4
+ VERSION = '5.0.4'
5
5
 
6
6
  MIN_SUPPORTED_MEMCACHED_VERSION = '1.6'
7
7
  end
data/lib/dalli.rb CHANGED
@@ -61,6 +61,7 @@ end
61
61
  require_relative 'dalli/version'
62
62
  require_relative 'dalli/instrumentation'
63
63
 
64
+ require_relative 'dalli/flags'
64
65
  require_relative 'dalli/compressor'
65
66
  require_relative 'dalli/client'
66
67
  require_relative 'dalli/key_manager'
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: 5.0.3
4
+ version: 5.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter M. Goldstein
@@ -40,6 +40,7 @@ files:
40
40
  - lib/dalli/cas/client.rb
41
41
  - lib/dalli/client.rb
42
42
  - lib/dalli/compressor.rb
43
+ - lib/dalli/flags.rb
43
44
  - lib/dalli/instrumentation.rb
44
45
  - lib/dalli/key_manager.rb
45
46
  - lib/dalli/options.rb