dalli 5.1.6 → 5.1.8
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 +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/dalli/pipelined_setter.rb +8 -8
- data/lib/dalli/protocol/meta.rb +12 -2
- data/lib/dalli/protocol/request_formatter.rb +22 -3
- data/lib/dalli/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aedfdf5af128f44424f0d21689f66a86813b9714677716854889788fe3b62546
|
|
4
|
+
data.tar.gz: 4375bcb70c31f53ac8fbf13cc4bc16171756a87148f95c024d214d8028216795
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ea2568b866c13f7d3bb9bf7d0c305c2164503df325c029d5aa160edb1316bc8ff01f97ec30d46e8a5113ed49350f6813c915f6202a093c7d28b21f9aed690cf0
|
|
7
|
+
data.tar.gz: 2dac25033ab69bc1819eae18a94e2f7b4b672e540438e94f6aa8d73fe414baa47b17d77a65137b667ee1a9d0c57927477e30563b34c08d1cf4dbfde5f760ca1f
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ Dalli Changelog
|
|
|
4
4
|
Unreleased
|
|
5
5
|
==========
|
|
6
6
|
|
|
7
|
+
5.1.8
|
|
8
|
+
==========
|
|
9
|
+
|
|
10
|
+
Bug fixes:
|
|
11
|
+
|
|
12
|
+
- Raw values in an encoding that isn't ASCII-compatible, such as UTF-16, raised `Encoding::CompatibilityError` from `set`, `add`, `replace`, `append`, `prepend` and `set_multi`, as did a single-server `set_multi` mixing non-ASCII UTF-8 values with binary ones (such as raw Strings of both kinds, or with a JSON serializer, a value containing `é` next to a compressed one). A `p_token` or `l_token` with non-ASCII characters, such as `é`, did the same for any binary value, including every Marshal-serialized one. The error also closed the connection, so in a `quiet` block, or within one server's part of a multi-server `set_multi`, writes buffered before it were silently lost. Values are now sent as their bytes, which is what memcached stores (#1269)
|
|
13
|
+
|
|
14
|
+
5.1.7
|
|
15
|
+
==========
|
|
16
|
+
|
|
17
|
+
Bug fixes:
|
|
18
|
+
|
|
19
|
+
- `set_multi` across more than one server stored `nil` for a Symbol key or a key over 250 bytes, in place of the value given
|
|
20
|
+
|
|
7
21
|
5.1.6
|
|
8
22
|
==========
|
|
9
23
|
|
|
@@ -43,9 +43,12 @@ module Dalli
|
|
|
43
43
|
|
|
44
44
|
private
|
|
45
45
|
|
|
46
|
+
# Values are looked up by each key as sent. The caller's key can't be
|
|
47
|
+
# rebuilt from it: a long key is digested, and a Symbol becomes a String.
|
|
46
48
|
def setup_requests(hash, ttl, req_options)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
pairs = hash.transform_keys { |k| @key_manager.validate_key(k.to_s) }
|
|
50
|
+
groups = groups_for_keys(pairs.keys)
|
|
51
|
+
make_set_requests(groups, pairs, ttl, req_options)
|
|
49
52
|
groups.keys
|
|
50
53
|
end
|
|
51
54
|
|
|
@@ -59,12 +62,10 @@ module Dalli
|
|
|
59
62
|
# RetryableNetworkError too -- since NetworkError < DalliError -- dropping
|
|
60
63
|
# this server's keys on a transient hiccup instead of retrying. Only a
|
|
61
64
|
# non-network DalliError should be swallowed here.
|
|
62
|
-
def make_set_requests(groups,
|
|
65
|
+
def make_set_requests(groups, pairs, ttl, req_options)
|
|
63
66
|
groups.each do |server, keys_for_server|
|
|
64
67
|
keys_for_server.each do |key|
|
|
65
|
-
|
|
66
|
-
value = hash[original_key]
|
|
67
|
-
server.request(:pipelined_set, key, value, ttl, req_options)
|
|
68
|
+
server.request(:pipelined_set, key, pairs[key], ttl, req_options)
|
|
68
69
|
rescue Dalli::NetworkError
|
|
69
70
|
raise
|
|
70
71
|
rescue Dalli::MarshalError, Dalli::ValueOverMaxSize => e
|
|
@@ -93,8 +94,7 @@ module Dalli
|
|
|
93
94
|
end
|
|
94
95
|
|
|
95
96
|
def groups_for_keys(keys)
|
|
96
|
-
|
|
97
|
-
groups = @ring.keys_grouped_by_server(validated_keys)
|
|
97
|
+
groups = @ring.keys_grouped_by_server(keys)
|
|
98
98
|
|
|
99
99
|
if (unfound_keys = groups.delete(nil))
|
|
100
100
|
Dalli.logger.debug do
|
data/lib/dalli/protocol/meta.rb
CHANGED
|
@@ -162,7 +162,7 @@ module Dalli
|
|
|
162
162
|
bitflags: bitflags, cas: cas,
|
|
163
163
|
ttl: ttl, mode: mode, quiet: quiet,
|
|
164
164
|
**routing_token_kwargs(options))
|
|
165
|
-
write(
|
|
165
|
+
write(request_with_value(req, value))
|
|
166
166
|
@connection_manager.flush unless quiet
|
|
167
167
|
end
|
|
168
168
|
# rubocop:enable Metrics/ParameterLists
|
|
@@ -183,10 +183,20 @@ module Dalli
|
|
|
183
183
|
req = RequestFormatter.meta_set(key: key, value: value,
|
|
184
184
|
cas: cas, ttl: ttl, mode: mode, quiet: quiet?,
|
|
185
185
|
**routing_token_kwargs(options))
|
|
186
|
-
write(
|
|
186
|
+
write(request_with_value(req, value))
|
|
187
187
|
@connection_manager.flush unless quiet?
|
|
188
188
|
end
|
|
189
189
|
|
|
190
|
+
# Ruby refuses to join Strings whose encodings clash, such as a raw
|
|
191
|
+
# UTF-16 value, or a routing token with non-ASCII characters next to a
|
|
192
|
+
# binary value. memcached stores bytes, so join the bytes then.
|
|
193
|
+
# Joining the Strings first keeps the common case free of extra checks.
|
|
194
|
+
def request_with_value(req, value)
|
|
195
|
+
"#{req}#{value}#{TERMINATOR}"
|
|
196
|
+
rescue Encoding::CompatibilityError
|
|
197
|
+
"#{req.b}#{value.b}#{TERMINATOR}"
|
|
198
|
+
end
|
|
199
|
+
|
|
190
200
|
# Delete Commands
|
|
191
201
|
#
|
|
192
202
|
# `options` supports the meta-delete keys :invalidate, :tombstone_ttl and
|
|
@@ -107,8 +107,9 @@ module Dalli
|
|
|
107
107
|
|
|
108
108
|
def multi_meta_set(entries, ttl: nil, p_token: nil, l_token: nil)
|
|
109
109
|
# Routing tokens apply to every entry in the batch, so the suffix is
|
|
110
|
-
# built once rather than per entry.
|
|
111
|
-
|
|
110
|
+
# built once rather than per entry. It's binary, like the buffer, so
|
|
111
|
+
# a token with non-ASCII characters doesn't turn the buffer UTF-8.
|
|
112
|
+
token_suffix = routing_tokens(p_token: p_token, l_token: l_token).b
|
|
112
113
|
ttl = integer_flag(:ttl, ttl) if ttl
|
|
113
114
|
|
|
114
115
|
buffer = ''.b
|
|
@@ -123,11 +124,29 @@ module Dalli
|
|
|
123
124
|
buffer << ' b' if base64
|
|
124
125
|
buffer << " F#{bitflags}" if bitflags
|
|
125
126
|
buffer << " T#{ttl}" if ttl
|
|
126
|
-
buffer << ' MS q' << token_suffix << TERMINATOR
|
|
127
|
+
buffer << ' MS q' << token_suffix << TERMINATOR
|
|
128
|
+
append_bytes(buffer, value)
|
|
129
|
+
buffer << TERMINATOR
|
|
127
130
|
end
|
|
128
131
|
buffer << META_NOOP
|
|
129
132
|
end
|
|
130
133
|
|
|
134
|
+
# Values are appended as bytes. One batch can hold UTF-8 and binary
|
|
135
|
+
# values, which String#<< refuses to combine, and a raw value can be in
|
|
136
|
+
# an encoding that isn't ASCII-compatible, such as UTF-16.
|
|
137
|
+
# Don't chain on the result: TruffleRuby's append_as_bytes returns its
|
|
138
|
+
# arguments rather than the buffer.
|
|
139
|
+
if String.method_defined?(:append_as_bytes)
|
|
140
|
+
def append_bytes(buffer, value)
|
|
141
|
+
buffer.append_as_bytes(value)
|
|
142
|
+
end
|
|
143
|
+
else
|
|
144
|
+
def append_bytes(buffer, value)
|
|
145
|
+
buffer << (value.encoding == Encoding::BINARY ? value : value.b)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
private :append_bytes
|
|
149
|
+
|
|
131
150
|
# Thundering herd protection flag:
|
|
132
151
|
# - stale (I flag): Instead of deleting the item, mark it as stale. Other clients
|
|
133
152
|
# using N/R flags will see the X flag and know the item is being regenerated.
|
data/lib/dalli/version.rb
CHANGED