dalli 4.3.3 → 5.0.2
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 +80 -0
- data/Gemfile +1 -0
- data/README.md +4 -16
- data/lib/dalli/client.rb +72 -46
- data/lib/dalli/instrumentation.rb +3 -1
- data/lib/dalli/options.rb +1 -1
- data/lib/dalli/pid_cache.rb +1 -1
- data/lib/dalli/pipelined_getter.rb +0 -2
- data/lib/dalli/protocol/base.rb +12 -14
- data/lib/dalli/protocol/connection_manager.rb +9 -3
- data/lib/dalli/protocol/meta.rb +77 -5
- data/lib/dalli/protocol/server_config_parser.rb +1 -1
- data/lib/dalli/ring.rb +2 -2
- data/lib/dalli/servers_arg_normalizer.rb +1 -1
- data/lib/dalli/socket.rb +4 -0
- data/lib/dalli/version.rb +2 -2
- data/lib/dalli.rb +2 -4
- metadata +6 -12
- data/lib/dalli/protocol/binary/request_formatter.rb +0 -117
- data/lib/dalli/protocol/binary/response_header.rb +0 -36
- data/lib/dalli/protocol/binary/response_processor.rb +0 -229
- data/lib/dalli/protocol/binary/sasl_authentication.rb +0 -60
- data/lib/dalli/protocol/binary.rb +0 -200
- data/lib/dalli/protocol_deprecations.rb +0 -45
- /data/lib/dalli/protocol/{meta/key_regularizer.rb → key_regularizer.rb} +0 -0
- /data/lib/dalli/protocol/{meta/request_formatter.rb → request_formatter.rb} +0 -0
- /data/lib/dalli/protocol/{meta/response_processor.rb → response_processor.rb} +0 -0
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'forwardable'
|
|
4
|
-
require 'socket'
|
|
5
|
-
require 'timeout'
|
|
6
|
-
|
|
7
|
-
module Dalli
|
|
8
|
-
module Protocol
|
|
9
|
-
##
|
|
10
|
-
# Access point for a single Memcached server, accessed via Memcached's binary
|
|
11
|
-
# protocol. Contains logic for managing connection state to the server (retries, etc),
|
|
12
|
-
# formatting requests to the server, and unpacking responses.
|
|
13
|
-
##
|
|
14
|
-
class Binary < Base
|
|
15
|
-
def response_processor
|
|
16
|
-
@response_processor ||= ResponseProcessor.new(@connection_manager, @value_marshaller)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
# Retrieval Commands
|
|
22
|
-
def get(key, options = nil)
|
|
23
|
-
req = RequestFormatter.standard_request(opkey: :get, key: key)
|
|
24
|
-
write(req)
|
|
25
|
-
@connection_manager.flush
|
|
26
|
-
response_processor.get(cache_nils: cache_nils?(options))
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def quiet_get_request(key)
|
|
30
|
-
RequestFormatter.standard_request(opkey: :getkq, key: key)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def gat(key, ttl, options = nil)
|
|
34
|
-
ttl = TtlSanitizer.sanitize(ttl)
|
|
35
|
-
req = RequestFormatter.standard_request(opkey: :gat, key: key, ttl: ttl)
|
|
36
|
-
write(req)
|
|
37
|
-
@connection_manager.flush
|
|
38
|
-
response_processor.get(cache_nils: cache_nils?(options))
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def touch(key, ttl)
|
|
42
|
-
ttl = TtlSanitizer.sanitize(ttl)
|
|
43
|
-
write(RequestFormatter.standard_request(opkey: :touch, key: key, ttl: ttl))
|
|
44
|
-
@connection_manager.flush
|
|
45
|
-
response_processor.generic_response
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# TODO: This is confusing, as there's a cas command in memcached
|
|
49
|
-
# and this isn't it. Maybe rename? Maybe eliminate?
|
|
50
|
-
def cas(key)
|
|
51
|
-
req = RequestFormatter.standard_request(opkey: :get, key: key)
|
|
52
|
-
write(req)
|
|
53
|
-
@connection_manager.flush
|
|
54
|
-
response_processor.data_cas_response
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Storage Commands
|
|
58
|
-
def set(key, value, ttl, cas, options)
|
|
59
|
-
opkey = quiet? ? :setq : :set
|
|
60
|
-
storage_req(opkey, key, value, ttl, cas, options)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Pipelined set - writes a quiet set request without reading response.
|
|
64
|
-
# Used by PipelinedSetter for bulk operations.
|
|
65
|
-
def pipelined_set(key, value, ttl, options)
|
|
66
|
-
storage_req(:setq, key, value, ttl, 0, options)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def add(key, value, ttl, options)
|
|
70
|
-
opkey = quiet? ? :addq : :add
|
|
71
|
-
storage_req(opkey, key, value, ttl, 0, options)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def replace(key, value, ttl, cas, options)
|
|
75
|
-
opkey = quiet? ? :replaceq : :replace
|
|
76
|
-
storage_req(opkey, key, value, ttl, cas, options)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# rubocop:disable Metrics/ParameterLists
|
|
80
|
-
def storage_req(opkey, key, value, ttl, cas, options)
|
|
81
|
-
(value, bitflags) = @value_marshaller.store(key, value, options)
|
|
82
|
-
ttl = TtlSanitizer.sanitize(ttl)
|
|
83
|
-
|
|
84
|
-
req = RequestFormatter.standard_request(opkey: opkey, key: key,
|
|
85
|
-
value: value, bitflags: bitflags,
|
|
86
|
-
ttl: ttl, cas: cas)
|
|
87
|
-
write(req)
|
|
88
|
-
@connection_manager.flush unless quiet?
|
|
89
|
-
response_processor.storage_response unless quiet?
|
|
90
|
-
end
|
|
91
|
-
# rubocop:enable Metrics/ParameterLists
|
|
92
|
-
|
|
93
|
-
def append(key, value)
|
|
94
|
-
opkey = quiet? ? :appendq : :append
|
|
95
|
-
write_append_prepend opkey, key, value
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def prepend(key, value)
|
|
99
|
-
opkey = quiet? ? :prependq : :prepend
|
|
100
|
-
write_append_prepend opkey, key, value
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def write_append_prepend(opkey, key, value)
|
|
104
|
-
write(RequestFormatter.standard_request(opkey: opkey, key: key, value: value))
|
|
105
|
-
@connection_manager.flush unless quiet?
|
|
106
|
-
response_processor.no_body_response unless quiet?
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# Delete Commands
|
|
110
|
-
def delete(key, cas)
|
|
111
|
-
opkey = quiet? ? :deleteq : :delete
|
|
112
|
-
req = RequestFormatter.standard_request(opkey: opkey, key: key, cas: cas)
|
|
113
|
-
write(req)
|
|
114
|
-
@connection_manager.flush unless quiet?
|
|
115
|
-
response_processor.delete unless quiet?
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Pipelined delete - writes a quiet delete request without reading response.
|
|
119
|
-
# Used by PipelinedDeleter for bulk operations.
|
|
120
|
-
def pipelined_delete(key)
|
|
121
|
-
req = RequestFormatter.standard_request(opkey: :deleteq, key: key, cas: 0)
|
|
122
|
-
write(req)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Arithmetic Commands
|
|
126
|
-
def decr(key, count, ttl, initial)
|
|
127
|
-
opkey = quiet? ? :decrq : :decr
|
|
128
|
-
decr_incr opkey, key, count, ttl, initial
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def incr(key, count, ttl, initial)
|
|
132
|
-
opkey = quiet? ? :incrq : :incr
|
|
133
|
-
decr_incr opkey, key, count, ttl, initial
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# This allows us to special case a nil initial value, and
|
|
137
|
-
# handle it differently than a zero. This special value
|
|
138
|
-
# for expiry causes memcached to return a not found
|
|
139
|
-
# if the key doesn't already exist, rather than
|
|
140
|
-
# setting the initial value
|
|
141
|
-
NOT_FOUND_EXPIRY = 0xFFFFFFFF
|
|
142
|
-
private_constant :NOT_FOUND_EXPIRY
|
|
143
|
-
|
|
144
|
-
def decr_incr(opkey, key, count, ttl, initial)
|
|
145
|
-
expiry = initial ? TtlSanitizer.sanitize(ttl) : NOT_FOUND_EXPIRY
|
|
146
|
-
initial ||= 0
|
|
147
|
-
write(RequestFormatter.decr_incr_request(opkey: opkey, key: key,
|
|
148
|
-
count: count, initial: initial, expiry: expiry))
|
|
149
|
-
@connection_manager.flush unless quiet?
|
|
150
|
-
response_processor.decr_incr unless quiet?
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# Other Commands
|
|
154
|
-
def flush(ttl = 0)
|
|
155
|
-
opkey = quiet? ? :flushq : :flush
|
|
156
|
-
write(RequestFormatter.standard_request(opkey: opkey, ttl: ttl))
|
|
157
|
-
@connection_manager.flush unless quiet?
|
|
158
|
-
response_processor.no_body_response unless quiet?
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Noop is a keepalive operation but also used to demarcate the end of a set of pipelined commands.
|
|
162
|
-
# We need to read all the responses at once.
|
|
163
|
-
def noop
|
|
164
|
-
write_noop
|
|
165
|
-
response_processor.consume_all_responses_until_noop
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def stats(info = '')
|
|
169
|
-
req = RequestFormatter.standard_request(opkey: :stat, key: info)
|
|
170
|
-
write(req)
|
|
171
|
-
@connection_manager.flush
|
|
172
|
-
response_processor.stats
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def reset_stats
|
|
176
|
-
write(RequestFormatter.standard_request(opkey: :stat, key: 'reset'))
|
|
177
|
-
@connection_manager.flush
|
|
178
|
-
response_processor.reset
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def version
|
|
182
|
-
write(RequestFormatter.standard_request(opkey: :version))
|
|
183
|
-
@connection_manager.flush
|
|
184
|
-
response_processor.version
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def write_noop
|
|
188
|
-
req = RequestFormatter.standard_request(opkey: :noop)
|
|
189
|
-
write(req)
|
|
190
|
-
@connection_manager.flush
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
require_relative 'binary/request_formatter'
|
|
194
|
-
require_relative 'binary/response_header'
|
|
195
|
-
require_relative 'binary/response_processor'
|
|
196
|
-
require_relative 'binary/sasl_authentication'
|
|
197
|
-
include SaslAuthentication
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Dalli
|
|
4
|
-
##
|
|
5
|
-
# Handles deprecation warnings for protocol and authentication features
|
|
6
|
-
# that will be removed in Dalli 5.0.
|
|
7
|
-
##
|
|
8
|
-
module ProtocolDeprecations
|
|
9
|
-
BINARY_PROTOCOL_DEPRECATION_MESSAGE = <<~MSG.chomp
|
|
10
|
-
[DEPRECATION] The binary protocol is deprecated and will be removed in Dalli 5.0. \
|
|
11
|
-
Please use `protocol: :meta` instead. The meta protocol requires memcached 1.6+. \
|
|
12
|
-
See https://github.com/petergoldstein/dalli for migration details.
|
|
13
|
-
MSG
|
|
14
|
-
|
|
15
|
-
SASL_AUTH_DEPRECATION_MESSAGE = <<~MSG.chomp
|
|
16
|
-
[DEPRECATION] SASL authentication is deprecated and will be removed in Dalli 5.0. \
|
|
17
|
-
SASL is only supported by the binary protocol, which is being removed. \
|
|
18
|
-
Consider using network-level security (firewall rules, VPN) or memcached's TLS support instead.
|
|
19
|
-
MSG
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def emit_deprecation_warnings
|
|
24
|
-
emit_binary_protocol_deprecation_warning
|
|
25
|
-
emit_sasl_auth_deprecation_warning
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def emit_binary_protocol_deprecation_warning
|
|
29
|
-
protocol = @options[:protocol]
|
|
30
|
-
# Binary is used when protocol is nil, :binary, or 'binary'
|
|
31
|
-
return if protocol.to_s == 'meta'
|
|
32
|
-
|
|
33
|
-
warn BINARY_PROTOCOL_DEPRECATION_MESSAGE
|
|
34
|
-
Dalli.logger.warn(BINARY_PROTOCOL_DEPRECATION_MESSAGE)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def emit_sasl_auth_deprecation_warning
|
|
38
|
-
username = @options[:username] || ENV.fetch('MEMCACHE_USERNAME', nil)
|
|
39
|
-
return unless username
|
|
40
|
-
|
|
41
|
-
warn SASL_AUTH_DEPRECATION_MESSAGE
|
|
42
|
-
Dalli.logger.warn(SASL_AUTH_DEPRECATION_MESSAGE)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|