dalli 3.1.3 → 3.1.4
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.
- checksums.yaml +4 -4
- data/History.md +7 -0
- data/lib/dalli/protocol/base.rb +6 -10
- data/lib/dalli/protocol/binary/response_processor.rb +63 -33
- data/lib/dalli/protocol/binary.rb +8 -8
- data/lib/dalli/protocol/response_buffer.rb +4 -4
- data/lib/dalli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e687040436582dd13519490544b2b493c424dca476a2a9173a68dc216c61d7ba
|
4
|
+
data.tar.gz: 293d5d74a31562116c17a24b02192504483d066f03418fe44d99694092595f0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d47dc643fb3722b2718a6fd612525574ec1355889515b70499f56fb102f731a0be11ec010dec5e670bab1740f40e40b099347a5bf341c5754a97cf1a09206396
|
7
|
+
data.tar.gz: 6e993408f8ad08c275399d8f93542da58673207435fb171f9dcb39871f11d799bec412b721bb6c0bb3364d9d58fc1e1020533ed565e213db9b65cd2744505980
|
data/History.md
CHANGED
@@ -4,6 +4,13 @@ Dalli Changelog
|
|
4
4
|
Unreleased
|
5
5
|
==========
|
6
6
|
|
7
|
+
3.1.4
|
8
|
+
==========
|
9
|
+
|
10
|
+
- Improve response parsing performance (casperisfine)
|
11
|
+
- Reorganize binary protocol parsing a bit (petergoldstein)
|
12
|
+
- Fix handling of non-ASCII keys in get_multi (petergoldstein)
|
13
|
+
|
7
14
|
3.1.3
|
8
15
|
==========
|
9
16
|
|
data/lib/dalli/protocol/base.rb
CHANGED
@@ -83,20 +83,20 @@ module Dalli
|
|
83
83
|
|
84
84
|
response_buffer.read
|
85
85
|
|
86
|
-
|
87
|
-
#
|
86
|
+
status, cas, key, value = response_buffer.process_single_getk_response
|
87
|
+
# status is not nil only if we have a full response to parse
|
88
88
|
# in the buffer
|
89
|
-
|
89
|
+
until status.nil?
|
90
90
|
# If the status is ok and key is nil, then this is the response
|
91
91
|
# to the noop at the end of the pipeline
|
92
|
-
finish_pipeline && break if
|
92
|
+
finish_pipeline && break if status && key.nil?
|
93
93
|
|
94
94
|
# If the status is ok and the key is not nil, then this is a
|
95
95
|
# getkq response with a value that we want to set in the response hash
|
96
|
-
values[key] = [value,
|
96
|
+
values[key] = [value, cas] unless key.nil?
|
97
97
|
|
98
98
|
# Get the next response from the buffer
|
99
|
-
|
99
|
+
status, cas, key, value = response_buffer.process_single_getk_response
|
100
100
|
end
|
101
101
|
|
102
102
|
values
|
@@ -207,10 +207,6 @@ module Dalli
|
|
207
207
|
@response_buffer ||= ResponseBuffer.new(@connection_manager, response_processor)
|
208
208
|
end
|
209
209
|
|
210
|
-
def pipeline_response
|
211
|
-
response_buffer.process_single_getk_response
|
212
|
-
end
|
213
|
-
|
214
210
|
# Called after the noop response is received at the end of a set
|
215
211
|
# of pipelined gets
|
216
212
|
def finish_pipeline
|
@@ -46,11 +46,13 @@ module Dalli
|
|
46
46
|
[resp_header, body]
|
47
47
|
end
|
48
48
|
|
49
|
-
def unpack_response_body(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
def unpack_response_body(resp_header, body, parse_as_stored_value)
|
50
|
+
extra_len = resp_header.extra_len
|
51
|
+
key_len = resp_header.key_len
|
52
|
+
bitflags = extra_len.positive? ? body.unpack1('N') : 0x0
|
53
|
+
key = body.byteslice(extra_len, key_len).force_encoding('UTF-8') if key_len.positive?
|
54
|
+
value = body.byteslice((extra_len + key_len)..-1)
|
55
|
+
value = parse_as_stored_value ? @value_marshaller.retrieve(value, bitflags) : value
|
54
56
|
[key, value]
|
55
57
|
end
|
56
58
|
|
@@ -64,7 +66,7 @@ module Dalli
|
|
64
66
|
raise Dalli::DalliError, "Response error #{resp_header.status}: #{RESPONSE_CODES[resp_header.status]}"
|
65
67
|
end
|
66
68
|
|
67
|
-
def
|
69
|
+
def get(cache_nils: false)
|
68
70
|
resp_header, body = read_response
|
69
71
|
|
70
72
|
return false if resp_header.not_stored? # Not stored, normal status for add operation
|
@@ -73,7 +75,7 @@ module Dalli
|
|
73
75
|
raise_on_not_ok!(resp_header)
|
74
76
|
return true unless body
|
75
77
|
|
76
|
-
unpack_response_body(resp_header
|
78
|
+
unpack_response_body(resp_header, body, true).last
|
77
79
|
end
|
78
80
|
|
79
81
|
##
|
@@ -89,7 +91,7 @@ module Dalli
|
|
89
91
|
resp_header.cas
|
90
92
|
end
|
91
93
|
|
92
|
-
def
|
94
|
+
def delete
|
93
95
|
resp_header, = read_response
|
94
96
|
return false if resp_header.not_found? || resp_header.not_stored?
|
95
97
|
|
@@ -97,15 +99,7 @@ module Dalli
|
|
97
99
|
true
|
98
100
|
end
|
99
101
|
|
100
|
-
def
|
101
|
-
resp_header, = read_response
|
102
|
-
return false if resp_header.not_stored? # Not stored, possible status for append/prepend
|
103
|
-
|
104
|
-
raise_on_not_ok!(resp_header)
|
105
|
-
true
|
106
|
-
end
|
107
|
-
|
108
|
-
def data_cas_response(unpack: true)
|
102
|
+
def data_cas_response
|
109
103
|
resp_header, body = read_response
|
110
104
|
return [nil, resp_header.cas] if resp_header.not_found?
|
111
105
|
return [nil, false] if resp_header.not_stored?
|
@@ -113,14 +107,16 @@ module Dalli
|
|
113
107
|
raise_on_not_ok!(resp_header)
|
114
108
|
return [nil, resp_header.cas] unless body
|
115
109
|
|
116
|
-
[unpack_response_body(resp_header
|
110
|
+
[unpack_response_body(resp_header, body, true).last, resp_header.cas]
|
117
111
|
end
|
118
112
|
|
119
|
-
|
120
|
-
|
113
|
+
# Returns the new value for the key, if found and updated
|
114
|
+
def decr_incr
|
115
|
+
body = generic_response
|
116
|
+
body ? body.unpack1('Q>') : body
|
121
117
|
end
|
122
118
|
|
123
|
-
def
|
119
|
+
def stats
|
124
120
|
hash = {}
|
125
121
|
loop do
|
126
122
|
resp_header, body = read_response
|
@@ -133,14 +129,49 @@ module Dalli
|
|
133
129
|
# block to clear any error responses from inside the multi.
|
134
130
|
next unless resp_header.ok?
|
135
131
|
|
136
|
-
key, value = unpack_response_body(resp_header
|
132
|
+
key, value = unpack_response_body(resp_header, body, true)
|
137
133
|
hash[key] = value
|
138
134
|
end
|
139
135
|
end
|
140
136
|
|
141
|
-
def
|
142
|
-
|
143
|
-
|
137
|
+
def flush
|
138
|
+
no_body_response
|
139
|
+
end
|
140
|
+
|
141
|
+
def reset
|
142
|
+
generic_response
|
143
|
+
end
|
144
|
+
|
145
|
+
def version
|
146
|
+
generic_response
|
147
|
+
end
|
148
|
+
|
149
|
+
def consume_all_responses_until_noop
|
150
|
+
loop do
|
151
|
+
resp_header, = read_response
|
152
|
+
# This is the response to the terminating noop / end of stat
|
153
|
+
return true if resp_header.ok? && resp_header.key_len.zero?
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def generic_response
|
158
|
+
resp_header, body = read_response
|
159
|
+
|
160
|
+
return false if resp_header.not_stored? # Not stored, normal status for add operation
|
161
|
+
return nil if resp_header.not_found?
|
162
|
+
|
163
|
+
raise_on_not_ok!(resp_header)
|
164
|
+
return true unless body
|
165
|
+
|
166
|
+
unpack_response_body(resp_header, body, false).last
|
167
|
+
end
|
168
|
+
|
169
|
+
def no_body_response
|
170
|
+
resp_header, = read_response
|
171
|
+
return false if resp_header.not_stored? # Not stored, possible status for append/prepend/delete
|
172
|
+
|
173
|
+
raise_on_not_ok!(resp_header)
|
174
|
+
true
|
144
175
|
end
|
145
176
|
|
146
177
|
def validate_auth_format(extra_len, count)
|
@@ -164,8 +195,7 @@ module Dalli
|
|
164
195
|
end
|
165
196
|
|
166
197
|
def response_header_from_buffer(buf)
|
167
|
-
|
168
|
-
ResponseHeader.new(header)
|
198
|
+
ResponseHeader.new(buf)
|
169
199
|
end
|
170
200
|
|
171
201
|
##
|
@@ -180,7 +210,7 @@ module Dalli
|
|
180
210
|
##
|
181
211
|
def getk_response_from_buffer(buf)
|
182
212
|
# There's no header in the buffer, so don't advance
|
183
|
-
return [0, nil, nil, nil] unless contains_header?(buf)
|
213
|
+
return [0, nil, nil, nil, nil] unless contains_header?(buf)
|
184
214
|
|
185
215
|
resp_header = response_header_from_buffer(buf)
|
186
216
|
body_len = resp_header.body_len
|
@@ -189,18 +219,18 @@ module Dalli
|
|
189
219
|
# This is either the response to the terminating
|
190
220
|
# noop or, if the status is not zero, an intermediate
|
191
221
|
# error response that needs to be discarded.
|
192
|
-
return [ResponseHeader::SIZE, resp_header, nil, nil] if body_len.zero?
|
222
|
+
return [ResponseHeader::SIZE, resp_header.ok?, resp_header.cas, nil, nil] if body_len.zero?
|
193
223
|
|
194
224
|
resp_size = ResponseHeader::SIZE + body_len
|
195
225
|
# The header is in the buffer, but the body is not. As we don't have
|
196
226
|
# a complete response, don't advance the buffer
|
197
|
-
return [0, nil, nil, nil] unless buf.bytesize >= resp_size
|
227
|
+
return [0, nil, nil, nil, nil] unless buf.bytesize >= resp_size
|
198
228
|
|
199
229
|
# The full response is in our buffer, so parse it and return
|
200
230
|
# the values
|
201
|
-
body = buf.
|
202
|
-
key, value = unpack_response_body(resp_header
|
203
|
-
[resp_size, resp_header, key, value]
|
231
|
+
body = buf.byteslice(ResponseHeader::SIZE, body_len)
|
232
|
+
key, value = unpack_response_body(resp_header, body, true)
|
233
|
+
[resp_size, resp_header.ok?, resp_header.cas, key, value]
|
204
234
|
end
|
205
235
|
end
|
206
236
|
end
|
@@ -29,7 +29,7 @@ module Dalli
|
|
29
29
|
def get(key, options = nil)
|
30
30
|
req = RequestFormatter.standard_request(opkey: :get, key: key)
|
31
31
|
write(req)
|
32
|
-
response_processor.
|
32
|
+
response_processor.get(cache_nils: cache_nils?(options))
|
33
33
|
end
|
34
34
|
|
35
35
|
def quiet_get_request(key)
|
@@ -40,7 +40,7 @@ module Dalli
|
|
40
40
|
ttl = TtlSanitizer.sanitize(ttl)
|
41
41
|
req = RequestFormatter.standard_request(opkey: :gat, key: key, ttl: ttl)
|
42
42
|
write(req)
|
43
|
-
response_processor.
|
43
|
+
response_processor.get(cache_nils: cache_nils?(options))
|
44
44
|
end
|
45
45
|
|
46
46
|
def touch(key, ttl)
|
@@ -106,7 +106,7 @@ module Dalli
|
|
106
106
|
opkey = quiet? ? :deleteq : :delete
|
107
107
|
req = RequestFormatter.standard_request(opkey: opkey, key: key, cas: cas)
|
108
108
|
write(req)
|
109
|
-
response_processor.
|
109
|
+
response_processor.delete unless quiet?
|
110
110
|
end
|
111
111
|
|
112
112
|
# Arithmetic Commands
|
@@ -132,7 +132,7 @@ module Dalli
|
|
132
132
|
initial ||= 0
|
133
133
|
write(RequestFormatter.decr_incr_request(opkey: opkey, key: key,
|
134
134
|
count: count, initial: initial, expiry: expiry))
|
135
|
-
response_processor.
|
135
|
+
response_processor.decr_incr unless quiet?
|
136
136
|
end
|
137
137
|
|
138
138
|
# Other Commands
|
@@ -146,23 +146,23 @@ module Dalli
|
|
146
146
|
# We need to read all the responses at once.
|
147
147
|
def noop
|
148
148
|
write_noop
|
149
|
-
response_processor.
|
149
|
+
response_processor.consume_all_responses_until_noop
|
150
150
|
end
|
151
151
|
|
152
152
|
def stats(info = '')
|
153
153
|
req = RequestFormatter.standard_request(opkey: :stat, key: info)
|
154
154
|
write(req)
|
155
|
-
response_processor.
|
155
|
+
response_processor.stats
|
156
156
|
end
|
157
157
|
|
158
158
|
def reset_stats
|
159
159
|
write(RequestFormatter.standard_request(opkey: :stat, key: 'reset'))
|
160
|
-
response_processor.
|
160
|
+
response_processor.reset
|
161
161
|
end
|
162
162
|
|
163
163
|
def version
|
164
164
|
write(RequestFormatter.standard_request(opkey: :version))
|
165
|
-
response_processor.
|
165
|
+
response_processor.version
|
166
166
|
end
|
167
167
|
|
168
168
|
def write_noop
|
@@ -21,9 +21,9 @@ module Dalli
|
|
21
21
|
# Attempts to process a single response from the buffer. Starts
|
22
22
|
# by advancing the buffer to the specified start position
|
23
23
|
def process_single_getk_response
|
24
|
-
bytes,
|
24
|
+
bytes, status, cas, key, value = @response_processor.getk_response_from_buffer(@buffer)
|
25
25
|
advance(bytes)
|
26
|
-
[
|
26
|
+
[status, cas, key, value]
|
27
27
|
end
|
28
28
|
|
29
29
|
# Advances the internal response buffer by bytes_to_advance
|
@@ -31,13 +31,13 @@ module Dalli
|
|
31
31
|
def advance(bytes_to_advance)
|
32
32
|
return unless bytes_to_advance.positive?
|
33
33
|
|
34
|
-
@buffer = @buffer
|
34
|
+
@buffer = @buffer.byteslice(bytes_to_advance..-1)
|
35
35
|
end
|
36
36
|
|
37
37
|
# Resets the internal buffer to an empty state,
|
38
38
|
# so that we're ready to read pipelined responses
|
39
39
|
def reset
|
40
|
-
@buffer =
|
40
|
+
@buffer = ''.b
|
41
41
|
end
|
42
42
|
|
43
43
|
# Clear the internal response buffer
|
data/lib/dalli/version.rb
CHANGED
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: 3.1.
|
4
|
+
version: 3.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter M. Goldstein
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-12-
|
12
|
+
date: 2021-12-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: connection_pool
|