redis 4.0.3 → 4.5.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +110 -0
- data/README.md +126 -17
- data/lib/redis/client.rb +130 -82
- data/lib/redis/cluster/command_loader.rb +8 -7
- data/lib/redis/cluster/node.rb +5 -1
- data/lib/redis/cluster/node_key.rb +3 -7
- data/lib/redis/cluster/node_loader.rb +2 -0
- data/lib/redis/cluster/option.rb +31 -14
- data/lib/redis/cluster/slot.rb +30 -13
- data/lib/redis/cluster/slot_loader.rb +6 -4
- data/lib/redis/cluster.rb +23 -17
- data/lib/redis/connection/command_helper.rb +5 -2
- data/lib/redis/connection/hiredis.rb +4 -3
- data/lib/redis/connection/registry.rb +2 -1
- data/lib/redis/connection/ruby.rb +139 -106
- data/lib/redis/connection/synchrony.rb +9 -4
- data/lib/redis/connection.rb +2 -0
- data/lib/redis/distributed.rb +171 -70
- data/lib/redis/errors.rb +2 -0
- data/lib/redis/hash_ring.rb +15 -14
- data/lib/redis/pipeline.rb +46 -8
- data/lib/redis/subscribe.rb +11 -12
- data/lib/redis/version.rb +3 -1
- data/lib/redis.rb +1239 -426
- metadata +16 -262
- data/.gitignore +0 -19
- data/.travis/Gemfile +0 -18
- data/.travis.yml +0 -61
- data/.yardopts +0 -3
- data/Gemfile +0 -8
- data/benchmarking/logging.rb +0 -71
- data/benchmarking/pipeline.rb +0 -51
- data/benchmarking/speed.rb +0 -21
- data/benchmarking/suite.rb +0 -24
- data/benchmarking/worker.rb +0 -71
- data/bin/build +0 -71
- data/bors.toml +0 -14
- data/examples/basic.rb +0 -15
- data/examples/consistency.rb +0 -114
- data/examples/dist_redis.rb +0 -43
- data/examples/incr-decr.rb +0 -17
- data/examples/list.rb +0 -26
- data/examples/pubsub.rb +0 -37
- data/examples/sentinel/sentinel.conf +0 -9
- data/examples/sentinel/start +0 -49
- data/examples/sentinel.rb +0 -41
- data/examples/sets.rb +0 -36
- data/examples/unicorn/config.ru +0 -3
- data/examples/unicorn/unicorn.rb +0 -20
- data/makefile +0 -74
- data/redis.gemspec +0 -43
- data/test/bitpos_test.rb +0 -63
- data/test/blocking_commands_test.rb +0 -40
- data/test/client_test.rb +0 -76
- data/test/cluster_abnormal_state_test.rb +0 -38
- data/test/cluster_blocking_commands_test.rb +0 -15
- data/test/cluster_client_internals_test.rb +0 -77
- data/test/cluster_client_key_hash_tags_test.rb +0 -88
- data/test/cluster_client_options_test.rb +0 -147
- data/test/cluster_client_pipelining_test.rb +0 -59
- data/test/cluster_client_replicas_test.rb +0 -36
- data/test/cluster_client_slots_test.rb +0 -94
- data/test/cluster_client_transactions_test.rb +0 -71
- data/test/cluster_commands_on_cluster_test.rb +0 -165
- data/test/cluster_commands_on_connection_test.rb +0 -40
- data/test/cluster_commands_on_geo_test.rb +0 -74
- data/test/cluster_commands_on_hashes_test.rb +0 -11
- data/test/cluster_commands_on_hyper_log_log_test.rb +0 -17
- data/test/cluster_commands_on_keys_test.rb +0 -134
- data/test/cluster_commands_on_lists_test.rb +0 -15
- data/test/cluster_commands_on_pub_sub_test.rb +0 -101
- data/test/cluster_commands_on_scripting_test.rb +0 -56
- data/test/cluster_commands_on_server_test.rb +0 -221
- data/test/cluster_commands_on_sets_test.rb +0 -39
- data/test/cluster_commands_on_sorted_sets_test.rb +0 -35
- data/test/cluster_commands_on_streams_test.rb +0 -196
- data/test/cluster_commands_on_strings_test.rb +0 -15
- data/test/cluster_commands_on_transactions_test.rb +0 -41
- data/test/cluster_commands_on_value_types_test.rb +0 -14
- data/test/command_map_test.rb +0 -28
- data/test/commands_on_geo_test.rb +0 -116
- data/test/commands_on_hashes_test.rb +0 -7
- data/test/commands_on_hyper_log_log_test.rb +0 -7
- data/test/commands_on_lists_test.rb +0 -7
- data/test/commands_on_sets_test.rb +0 -7
- data/test/commands_on_sorted_sets_test.rb +0 -7
- data/test/commands_on_strings_test.rb +0 -7
- data/test/commands_on_value_types_test.rb +0 -207
- data/test/connection_handling_test.rb +0 -275
- data/test/connection_test.rb +0 -57
- data/test/db/.gitkeep +0 -0
- data/test/distributed_blocking_commands_test.rb +0 -52
- data/test/distributed_commands_on_hashes_test.rb +0 -21
- data/test/distributed_commands_on_hyper_log_log_test.rb +0 -26
- data/test/distributed_commands_on_lists_test.rb +0 -19
- data/test/distributed_commands_on_sets_test.rb +0 -105
- data/test/distributed_commands_on_sorted_sets_test.rb +0 -59
- data/test/distributed_commands_on_strings_test.rb +0 -79
- data/test/distributed_commands_on_value_types_test.rb +0 -129
- data/test/distributed_commands_requiring_clustering_test.rb +0 -162
- data/test/distributed_connection_handling_test.rb +0 -21
- data/test/distributed_internals_test.rb +0 -68
- data/test/distributed_key_tags_test.rb +0 -50
- data/test/distributed_persistence_control_commands_test.rb +0 -24
- data/test/distributed_publish_subscribe_test.rb +0 -90
- data/test/distributed_remote_server_control_commands_test.rb +0 -64
- data/test/distributed_scripting_test.rb +0 -100
- data/test/distributed_sorting_test.rb +0 -18
- data/test/distributed_test.rb +0 -56
- data/test/distributed_transactions_test.rb +0 -30
- data/test/encoding_test.rb +0 -14
- data/test/error_replies_test.rb +0 -57
- data/test/fork_safety_test.rb +0 -60
- data/test/helper.rb +0 -345
- data/test/helper_test.rb +0 -22
- data/test/internals_test.rb +0 -408
- data/test/lint/blocking_commands.rb +0 -174
- data/test/lint/hashes.rb +0 -203
- data/test/lint/hyper_log_log.rb +0 -74
- data/test/lint/lists.rb +0 -159
- data/test/lint/sets.rb +0 -282
- data/test/lint/sorted_sets.rb +0 -497
- data/test/lint/strings.rb +0 -348
- data/test/lint/value_types.rb +0 -130
- data/test/persistence_control_commands_test.rb +0 -24
- data/test/pipelining_commands_test.rb +0 -246
- data/test/publish_subscribe_test.rb +0 -280
- data/test/remote_server_control_commands_test.rb +0 -175
- data/test/scanning_test.rb +0 -407
- data/test/scripting_test.rb +0 -76
- data/test/sentinel_command_test.rb +0 -78
- data/test/sentinel_test.rb +0 -253
- data/test/sorting_test.rb +0 -57
- data/test/ssl_test.rb +0 -69
- data/test/support/cluster/orchestrator.rb +0 -199
- data/test/support/connection/hiredis.rb +0 -1
- data/test/support/connection/ruby.rb +0 -1
- data/test/support/connection/synchrony.rb +0 -17
- data/test/support/redis_mock.rb +0 -130
- data/test/support/ssl/gen_certs.sh +0 -31
- data/test/support/ssl/trusted-ca.crt +0 -25
- data/test/support/ssl/trusted-ca.key +0 -27
- data/test/support/ssl/trusted-cert.crt +0 -81
- data/test/support/ssl/trusted-cert.key +0 -28
- data/test/support/ssl/untrusted-ca.crt +0 -26
- data/test/support/ssl/untrusted-ca.key +0 -27
- data/test/support/ssl/untrusted-cert.crt +0 -82
- data/test/support/ssl/untrusted-cert.key +0 -28
- data/test/support/wire/synchrony.rb +0 -24
- data/test/support/wire/thread.rb +0 -5
- data/test/synchrony_driver.rb +0 -85
- data/test/test.conf.erb +0 -9
- data/test/thread_safety_test.rb +0 -60
- data/test/transactions_test.rb +0 -272
- data/test/unknown_commands_test.rb +0 -12
- data/test/url_param_test.rb +0 -136
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "registry"
|
2
4
|
require_relative "command_helper"
|
3
5
|
require_relative "../errors"
|
@@ -13,8 +15,7 @@ end
|
|
13
15
|
class Redis
|
14
16
|
module Connection
|
15
17
|
module SocketMixin
|
16
|
-
|
17
|
-
CRLF = "\r\n".freeze
|
18
|
+
CRLF = "\r\n"
|
18
19
|
|
19
20
|
def initialize(*args)
|
20
21
|
super(*args)
|
@@ -24,97 +25,92 @@ class Redis
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def timeout=(timeout)
|
27
|
-
if timeout && timeout > 0
|
28
|
-
@timeout = timeout
|
29
|
-
else
|
30
|
-
@timeout = nil
|
31
|
-
end
|
28
|
+
@timeout = (timeout if timeout && timeout > 0)
|
32
29
|
end
|
33
30
|
|
34
31
|
def write_timeout=(timeout)
|
35
|
-
if timeout && timeout > 0
|
36
|
-
@write_timeout = timeout
|
37
|
-
else
|
38
|
-
@write_timeout = nil
|
39
|
-
end
|
32
|
+
@write_timeout = (timeout if timeout && timeout > 0)
|
40
33
|
end
|
41
34
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
result
|
35
|
+
string_capacity_support = begin
|
36
|
+
String.new(capacity: 0)
|
37
|
+
true # Ruby 2.4+
|
38
|
+
rescue ArgumentError
|
39
|
+
false # Ruby 2.3
|
50
40
|
end
|
51
41
|
|
52
|
-
|
53
|
-
|
42
|
+
if string_capacity_support
|
43
|
+
def read(nbytes)
|
44
|
+
result = @buffer.slice!(0, nbytes)
|
54
45
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
46
|
+
buffer = String.new(capacity: nbytes, encoding: Encoding::ASCII_8BIT)
|
47
|
+
result << _read_from_socket(nbytes - result.bytesize, buffer) while result.bytesize < nbytes
|
58
48
|
|
59
|
-
|
60
|
-
|
49
|
+
result
|
50
|
+
end
|
51
|
+
else
|
52
|
+
def read(nbytes)
|
53
|
+
result = @buffer.slice!(0, nbytes)
|
61
54
|
|
62
|
-
|
55
|
+
result << _read_from_socket(nbytes - result.bytesize, "".b) while result.bytesize < nbytes
|
63
56
|
|
64
|
-
|
65
|
-
|
57
|
+
result
|
58
|
+
end
|
59
|
+
end
|
66
60
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
else
|
71
|
-
raise Redis::TimeoutError
|
72
|
-
end
|
73
|
-
rescue IO::WaitWritable
|
74
|
-
if IO.select(nil, [self], nil, @timeout)
|
75
|
-
retry
|
76
|
-
else
|
77
|
-
raise Redis::TimeoutError
|
78
|
-
end
|
61
|
+
def gets
|
62
|
+
while (crlf = @buffer.index(CRLF)).nil?
|
63
|
+
@buffer << _read_from_socket(16_384)
|
79
64
|
end
|
80
65
|
|
81
|
-
|
82
|
-
raise Errno::ECONNRESET
|
66
|
+
@buffer.slice!(0, crlf + CRLF.bytesize)
|
83
67
|
end
|
84
68
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
69
|
+
def _read_from_socket(nbytes, buffer = nil)
|
70
|
+
loop do
|
71
|
+
case chunk = read_nonblock(nbytes, buffer, exception: false)
|
72
|
+
when :wait_readable
|
73
|
+
unless wait_readable(@timeout)
|
74
|
+
raise Redis::TimeoutError
|
75
|
+
end
|
76
|
+
when :wait_writable
|
77
|
+
unless wait_writable(@timeout)
|
78
|
+
raise Redis::TimeoutError
|
79
|
+
end
|
80
|
+
when nil
|
81
|
+
raise Errno::ECONNRESET
|
82
|
+
when String
|
83
|
+
return chunk
|
100
84
|
end
|
101
85
|
end
|
102
|
-
|
103
|
-
rescue EOFError
|
104
|
-
raise Errno::ECONNRESET
|
105
86
|
end
|
106
87
|
|
107
|
-
def write(
|
108
|
-
return super(
|
88
|
+
def write(buffer)
|
89
|
+
return super(buffer) unless @write_timeout
|
109
90
|
|
110
|
-
|
111
|
-
|
91
|
+
bytes_to_write = buffer.bytesize
|
92
|
+
total_bytes_written = 0
|
112
93
|
loop do
|
113
|
-
|
94
|
+
case bytes_written = write_nonblock(buffer, exception: false)
|
95
|
+
when :wait_readable
|
96
|
+
unless wait_readable(@write_timeout)
|
97
|
+
raise Redis::TimeoutError
|
98
|
+
end
|
99
|
+
when :wait_writable
|
100
|
+
unless wait_writable(@write_timeout)
|
101
|
+
raise Redis::TimeoutError
|
102
|
+
end
|
103
|
+
when nil
|
104
|
+
raise Errno::ECONNRESET
|
105
|
+
when Integer
|
106
|
+
total_bytes_written += bytes_written
|
107
|
+
|
108
|
+
if total_bytes_written >= bytes_to_write
|
109
|
+
return total_bytes_written
|
110
|
+
end
|
114
111
|
|
115
|
-
|
116
|
-
|
117
|
-
data = data.byteslice(count..-1)
|
112
|
+
buffer = buffer.byteslice(bytes_written..-1)
|
113
|
+
end
|
118
114
|
end
|
119
115
|
end
|
120
116
|
end
|
@@ -124,7 +120,6 @@ class Redis
|
|
124
120
|
require "timeout"
|
125
121
|
|
126
122
|
class TCPSocket < ::TCPSocket
|
127
|
-
|
128
123
|
include SocketMixin
|
129
124
|
|
130
125
|
def self.connect(host, port, timeout)
|
@@ -140,7 +135,6 @@ class Redis
|
|
140
135
|
if defined?(::UNIXSocket)
|
141
136
|
|
142
137
|
class UNIXSocket < ::UNIXSocket
|
143
|
-
|
144
138
|
include SocketMixin
|
145
139
|
|
146
140
|
def self.connect(path, timeout)
|
@@ -152,13 +146,12 @@ class Redis
|
|
152
146
|
raise TimeoutError
|
153
147
|
end
|
154
148
|
|
155
|
-
# JRuby raises Errno::EAGAIN on #read_nonblock even when
|
149
|
+
# JRuby raises Errno::EAGAIN on #read_nonblock even when it
|
156
150
|
# says it is readable (1.6.6, in both 1.8 and 1.9 mode).
|
157
151
|
# Use the blocking #readpartial method instead.
|
158
152
|
|
159
153
|
def _read_from_socket(nbytes)
|
160
154
|
readpartial(nbytes)
|
161
|
-
|
162
155
|
rescue EOFError
|
163
156
|
raise Errno::ECONNRESET
|
164
157
|
end
|
@@ -169,19 +162,16 @@ class Redis
|
|
169
162
|
else
|
170
163
|
|
171
164
|
class TCPSocket < ::Socket
|
172
|
-
|
173
165
|
include SocketMixin
|
174
166
|
|
175
|
-
def self.connect_addrinfo(
|
176
|
-
sock = new(::Socket.const_get(
|
177
|
-
sockaddr = ::Socket.pack_sockaddr_in(port,
|
167
|
+
def self.connect_addrinfo(addrinfo, port, timeout)
|
168
|
+
sock = new(::Socket.const_get(addrinfo[0]), Socket::SOCK_STREAM, 0)
|
169
|
+
sockaddr = ::Socket.pack_sockaddr_in(port, addrinfo[3])
|
178
170
|
|
179
171
|
begin
|
180
172
|
sock.connect_nonblock(sockaddr)
|
181
173
|
rescue Errno::EINPROGRESS
|
182
|
-
|
183
|
-
raise TimeoutError
|
184
|
-
end
|
174
|
+
raise TimeoutError unless sock.wait_writable(timeout)
|
185
175
|
|
186
176
|
begin
|
187
177
|
sock.connect_nonblock(sockaddr)
|
@@ -220,14 +210,13 @@ class Redis
|
|
220
210
|
return connect_addrinfo(ai, port, timeout)
|
221
211
|
rescue SystemCallError
|
222
212
|
# Raise if this was our last attempt.
|
223
|
-
raise if addrinfo.length == i+1
|
213
|
+
raise if addrinfo.length == i + 1
|
224
214
|
end
|
225
215
|
end
|
226
216
|
end
|
227
217
|
end
|
228
218
|
|
229
219
|
class UNIXSocket < ::Socket
|
230
|
-
|
231
220
|
include SocketMixin
|
232
221
|
|
233
222
|
def self.connect(path, timeout)
|
@@ -237,9 +226,7 @@ class Redis
|
|
237
226
|
begin
|
238
227
|
sock.connect_nonblock(sockaddr)
|
239
228
|
rescue Errno::EINPROGRESS
|
240
|
-
|
241
|
-
raise TimeoutError
|
242
|
-
end
|
229
|
+
raise TimeoutError unless sock.wait_writable(timeout)
|
243
230
|
|
244
231
|
begin
|
245
232
|
sock.connect_nonblock(sockaddr)
|
@@ -257,18 +244,56 @@ class Redis
|
|
257
244
|
class SSLSocket < ::OpenSSL::SSL::SSLSocket
|
258
245
|
include SocketMixin
|
259
246
|
|
247
|
+
unless method_defined?(:wait_readable)
|
248
|
+
def wait_readable(timeout = nil)
|
249
|
+
to_io.wait_readable(timeout)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
unless method_defined?(:wait_writable)
|
254
|
+
def wait_writable(timeout = nil)
|
255
|
+
to_io.wait_writable(timeout)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
260
259
|
def self.connect(host, port, timeout, ssl_params)
|
261
260
|
# Note: this is using Redis::Connection::TCPSocket
|
262
261
|
tcp_sock = TCPSocket.connect(host, port, timeout)
|
263
262
|
|
264
263
|
ctx = OpenSSL::SSL::SSLContext.new
|
265
|
-
|
264
|
+
|
265
|
+
# The provided parameters are merged into OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
|
266
|
+
ctx.set_params(ssl_params || {})
|
266
267
|
|
267
268
|
ssl_sock = new(tcp_sock, ctx)
|
268
269
|
ssl_sock.hostname = host
|
269
|
-
ssl_sock.connect
|
270
270
|
|
271
|
-
|
271
|
+
begin
|
272
|
+
# Initiate the socket connection in the background. If it doesn't fail
|
273
|
+
# immediately it will raise an IO::WaitWritable (Errno::EINPROGRESS)
|
274
|
+
# indicating the connection is in progress.
|
275
|
+
# Unlike waiting for a tcp socket to connect, you can't time out ssl socket
|
276
|
+
# connections during the connect phase properly, because IO.select only partially works.
|
277
|
+
# Instead, you have to retry.
|
278
|
+
ssl_sock.connect_nonblock
|
279
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable
|
280
|
+
if ssl_sock.wait_readable(timeout)
|
281
|
+
retry
|
282
|
+
else
|
283
|
+
raise TimeoutError
|
284
|
+
end
|
285
|
+
rescue IO::WaitWritable
|
286
|
+
if ssl_sock.wait_writable(timeout)
|
287
|
+
retry
|
288
|
+
else
|
289
|
+
raise TimeoutError
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
unless ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE || (
|
294
|
+
ctx.respond_to?(:verify_hostname) &&
|
295
|
+
!ctx.verify_hostname
|
296
|
+
)
|
272
297
|
ssl_sock.post_connection_check(host)
|
273
298
|
end
|
274
299
|
|
@@ -280,15 +305,16 @@ class Redis
|
|
280
305
|
class Ruby
|
281
306
|
include Redis::Connection::CommandHelper
|
282
307
|
|
283
|
-
MINUS = "-"
|
284
|
-
PLUS = "+"
|
285
|
-
COLON = ":"
|
286
|
-
DOLLAR = "$"
|
287
|
-
ASTERISK = "*"
|
308
|
+
MINUS = "-"
|
309
|
+
PLUS = "+"
|
310
|
+
COLON = ":"
|
311
|
+
DOLLAR = "$"
|
312
|
+
ASTERISK = "*"
|
288
313
|
|
289
314
|
def self.connect(config)
|
290
315
|
if config[:scheme] == "unix"
|
291
316
|
raise ArgumentError, "SSL incompatible with unix sockets" if config[:ssl]
|
317
|
+
|
292
318
|
sock = UNIXSocket.connect(config[:path], config[:connect_timeout])
|
293
319
|
elsif config[:scheme] == "rediss" || config[:ssl]
|
294
320
|
sock = SSLSocket.connect(config[:host], config[:port], config[:connect_timeout], config[:ssl_params])
|
@@ -300,10 +326,11 @@ class Redis
|
|
300
326
|
instance.timeout = config[:read_timeout]
|
301
327
|
instance.write_timeout = config[:write_timeout]
|
302
328
|
instance.set_tcp_keepalive config[:tcp_keepalive]
|
329
|
+
instance.set_tcp_nodelay if sock.is_a? TCPSocket
|
303
330
|
instance
|
304
331
|
end
|
305
332
|
|
306
|
-
if [
|
333
|
+
if %i[SOL_SOCKET SO_KEEPALIVE SOL_TCP TCP_KEEPIDLE TCP_KEEPINTVL TCP_KEEPCNT].all? { |c| Socket.const_defined? c }
|
307
334
|
def set_tcp_keepalive(keepalive)
|
308
335
|
return unless keepalive.is_a?(Hash)
|
309
336
|
|
@@ -315,14 +342,13 @@ class Redis
|
|
315
342
|
|
316
343
|
def get_tcp_keepalive
|
317
344
|
{
|
318
|
-
:
|
319
|
-
:
|
320
|
-
:
|
345
|
+
time: @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE).int,
|
346
|
+
intvl: @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL).int,
|
347
|
+
probes: @sock.getsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT).int
|
321
348
|
}
|
322
349
|
end
|
323
350
|
else
|
324
|
-
def set_tcp_keepalive(keepalive)
|
325
|
-
end
|
351
|
+
def set_tcp_keepalive(keepalive); end
|
326
352
|
|
327
353
|
def get_tcp_keepalive
|
328
354
|
{
|
@@ -330,12 +356,21 @@ class Redis
|
|
330
356
|
end
|
331
357
|
end
|
332
358
|
|
359
|
+
# disables Nagle's Algorithm, prevents multiple round trips with MULTI
|
360
|
+
if %i[IPPROTO_TCP TCP_NODELAY].all? { |c| Socket.const_defined? c }
|
361
|
+
def set_tcp_nodelay
|
362
|
+
@sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
363
|
+
end
|
364
|
+
else
|
365
|
+
def set_tcp_nodelay; end
|
366
|
+
end
|
367
|
+
|
333
368
|
def initialize(sock)
|
334
369
|
@sock = sock
|
335
370
|
end
|
336
371
|
|
337
372
|
def connected?
|
338
|
-
|
373
|
+
!!@sock
|
339
374
|
end
|
340
375
|
|
341
376
|
def disconnect
|
@@ -346,9 +381,7 @@ class Redis
|
|
346
381
|
end
|
347
382
|
|
348
383
|
def timeout=(timeout)
|
349
|
-
if @sock.respond_to?(:timeout=)
|
350
|
-
@sock.timeout = timeout
|
351
|
-
end
|
384
|
+
@sock.timeout = timeout if @sock.respond_to?(:timeout=)
|
352
385
|
end
|
353
386
|
|
354
387
|
def write_timeout=(timeout)
|
@@ -363,7 +396,6 @@ class Redis
|
|
363
396
|
line = @sock.gets
|
364
397
|
reply_type = line.slice!(0, 1)
|
365
398
|
format_reply(reply_type, line)
|
366
|
-
|
367
399
|
rescue Errno::EAGAIN
|
368
400
|
raise TimeoutError
|
369
401
|
end
|
@@ -375,7 +407,7 @@ class Redis
|
|
375
407
|
when COLON then format_integer_reply(line)
|
376
408
|
when DOLLAR then format_bulk_reply(line)
|
377
409
|
when ASTERISK then format_multi_bulk_reply(line)
|
378
|
-
else raise ProtocolError
|
410
|
+
else raise ProtocolError, reply_type
|
379
411
|
end
|
380
412
|
end
|
381
413
|
|
@@ -394,6 +426,7 @@ class Redis
|
|
394
426
|
def format_bulk_reply(line)
|
395
427
|
bulklen = line.to_i
|
396
428
|
return if bulklen == -1
|
429
|
+
|
397
430
|
reply = encode(@sock.read(bulklen))
|
398
431
|
@sock.read(2) # Discard CRLF.
|
399
432
|
reply
|
@@ -1,9 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "command_helper"
|
2
4
|
require_relative "registry"
|
3
5
|
require_relative "../errors"
|
4
6
|
require "em-synchrony"
|
5
7
|
require "hiredis/reader"
|
6
8
|
|
9
|
+
Kernel.warn(
|
10
|
+
"The redis synchrony driver is deprecated and will be removed in redis-rb 5.0. " \
|
11
|
+
"We're looking for people to maintain it as a separate gem, see https://github.com/redis/redis-rb/issues/915"
|
12
|
+
)
|
13
|
+
|
7
14
|
class Redis
|
8
15
|
module Connection
|
9
16
|
class RedisClient < EventMachine::Connection
|
@@ -46,9 +53,7 @@ class Redis
|
|
46
53
|
|
47
54
|
def read
|
48
55
|
@req = EventMachine::DefaultDeferrable.new
|
49
|
-
if @timeout > 0
|
50
|
-
@req.timeout(@timeout, :timeout)
|
51
|
-
end
|
56
|
+
@req.timeout(@timeout, :timeout) if @timeout > 0
|
52
57
|
EventMachine::Synchrony.sync @req
|
53
58
|
end
|
54
59
|
|
@@ -105,7 +110,7 @@ class Redis
|
|
105
110
|
end
|
106
111
|
|
107
112
|
def connected?
|
108
|
-
@connection
|
113
|
+
@connection&.connected?
|
109
114
|
end
|
110
115
|
|
111
116
|
def timeout=(timeout)
|