dalli 4.3.10 → 5.0.0

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -161
  3. data/Gemfile +1 -1
  4. data/README.md +4 -55
  5. data/lib/dalli/client.rb +39 -98
  6. data/lib/dalli/compressor.rb +5 -53
  7. data/lib/dalli/instrumentation.rb +1 -1
  8. data/lib/dalli/key_manager.rb +2 -28
  9. data/lib/dalli/options.rb +2 -2
  10. data/lib/dalli/pipelined_getter.rb +32 -46
  11. data/lib/dalli/pipelined_setter.rb +8 -17
  12. data/lib/dalli/protocol/base.rb +31 -160
  13. data/lib/dalli/protocol/connection_manager.rb +20 -137
  14. data/lib/dalli/protocol/meta.rb +15 -54
  15. data/lib/dalli/protocol/{meta/request_formatter.rb → request_formatter.rb} +8 -21
  16. data/lib/dalli/protocol/response_buffer.rb +12 -27
  17. data/lib/dalli/protocol/{meta/response_processor.rb → response_processor.rb} +32 -64
  18. data/lib/dalli/protocol/server_config_parser.rb +1 -1
  19. data/lib/dalli/protocol/value_compressor.rb +7 -36
  20. data/lib/dalli/protocol/value_serializer.rb +1 -1
  21. data/lib/dalli/protocol.rb +9 -7
  22. data/lib/dalli/ring.rb +2 -2
  23. data/lib/dalli/servers_arg_normalizer.rb +1 -1
  24. data/lib/dalli/socket.rb +0 -29
  25. data/lib/dalli/version.rb +2 -2
  26. data/lib/dalli.rb +0 -3
  27. data/lib/rack/session/dalli.rb +2 -1
  28. metadata +7 -14
  29. data/lib/dalli/json_serializer.rb +0 -28
  30. data/lib/dalli/protocol/binary/request_formatter.rb +0 -116
  31. data/lib/dalli/protocol/binary/response_header.rb +0 -36
  32. data/lib/dalli/protocol/binary/response_processor.rb +0 -245
  33. data/lib/dalli/protocol/binary/sasl_authentication.rb +0 -60
  34. data/lib/dalli/protocol/binary.rb +0 -202
  35. data/lib/dalli/protocol_deprecations.rb +0 -45
  36. /data/lib/dalli/protocol/{meta/key_regularizer.rb → key_regularizer.rb} +0 -0
@@ -1,202 +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), raw: raw_request?(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), raw: raw_request?(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, options = nil)
51
- req = RequestFormatter.standard_request(opkey: :get, key: key)
52
- write(req)
53
- @connection_manager.flush
54
- response_processor.data_cas_response(raw: raw_request?(options))
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, quiet: true)
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-next Metrics/ParameterLists
80
- def storage_req(opkey, key, value, ttl, cas, options, quiet: quiet?)
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
-
92
- def append(key, value)
93
- opkey = quiet? ? :appendq : :append
94
- write_append_prepend opkey, key, value
95
- end
96
-
97
- def prepend(key, value)
98
- opkey = quiet? ? :prependq : :prepend
99
- write_append_prepend opkey, key, value
100
- end
101
-
102
- def write_append_prepend(opkey, key, value)
103
- write(RequestFormatter.standard_request(opkey: opkey, key: key, value: value))
104
- @connection_manager.flush unless quiet?
105
- response_processor.no_body_response unless quiet?
106
- end
107
-
108
- # Delete Commands
109
- def delete(key, cas)
110
- opkey = quiet? ? :deleteq : :delete
111
- req = RequestFormatter.standard_request(opkey: opkey, key: key, cas: cas)
112
- write(req)
113
- @connection_manager.flush unless quiet?
114
- response_processor.delete unless quiet?
115
- end
116
-
117
- # Pipelined delete - writes a quiet delete request without reading response.
118
- # Used by PipelinedDeleter for bulk operations.
119
- def pipelined_delete(key)
120
- req = RequestFormatter.standard_request(opkey: :deleteq, key: key, cas: 0)
121
- write(req)
122
- end
123
-
124
- # Arithmetic Commands
125
- def decr(key, count, ttl, initial)
126
- opkey = quiet? ? :decrq : :decr
127
- decr_incr opkey, key, count, ttl, initial
128
- end
129
-
130
- def incr(key, count, ttl, initial)
131
- opkey = quiet? ? :incrq : :incr
132
- decr_incr opkey, key, count, ttl, initial
133
- end
134
-
135
- # This allows us to special case a nil initial value, and
136
- # handle it differently than a zero. This special value
137
- # for expiry causes memcached to return a not found
138
- # if the key doesn't already exist, rather than
139
- # setting the initial value
140
- NOT_FOUND_EXPIRY = 0xFFFFFFFF
141
- private_constant :NOT_FOUND_EXPIRY
142
-
143
- def decr_incr(opkey, key, count, ttl, initial)
144
- expiry = initial ? TtlSanitizer.sanitize(ttl) : NOT_FOUND_EXPIRY
145
- initial ||= 0
146
- write(RequestFormatter.decr_incr_request(opkey: opkey, key: key,
147
- count: count, initial: initial, expiry: expiry))
148
- @connection_manager.flush unless quiet?
149
- response_processor.decr_incr unless quiet?
150
- end
151
-
152
- # Other Commands
153
- def flush(ttl = 0)
154
- opkey = quiet? ? :flushq : :flush
155
- write(RequestFormatter.standard_request(opkey: opkey, ttl: ttl))
156
- @connection_manager.flush unless quiet?
157
- response_processor.no_body_response unless quiet?
158
- end
159
-
160
- # Noop is a keepalive operation but also used to demarcate the end of a set of pipelined commands.
161
- # We need to read all the responses at once.
162
- def noop
163
- write_noop
164
- result = response_processor.consume_all_responses_until_noop
165
- # Everything up to and including the noop reply has been read
166
- @connection_manager.clear_quiet_responses_pending!
167
- result
168
- end
169
-
170
- def stats(info = '')
171
- req = RequestFormatter.standard_request(opkey: :stat, key: info)
172
- write(req)
173
- @connection_manager.flush
174
- response_processor.stats
175
- end
176
-
177
- def reset_stats
178
- write(RequestFormatter.standard_request(opkey: :stat, key: 'reset'))
179
- @connection_manager.flush
180
- response_processor.reset
181
- end
182
-
183
- def version
184
- write(RequestFormatter.standard_request(opkey: :version))
185
- @connection_manager.flush
186
- response_processor.version
187
- end
188
-
189
- def write_noop
190
- req = RequestFormatter.standard_request(opkey: :noop)
191
- write(req)
192
- @connection_manager.flush
193
- end
194
-
195
- require_relative 'binary/request_formatter'
196
- require_relative 'binary/response_header'
197
- require_relative 'binary/response_processor'
198
- require_relative 'binary/sasl_authentication'
199
- include SaslAuthentication
200
- end
201
- end
202
- 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