redis 4.2.2 → 4.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28eb23d20152436fc47f334f517c6fa62855e8e4711b44979cb05d86f8dcdd34
4
- data.tar.gz: 46d01b3f5539800142582aeb7ebeabe4327bce970e31ce2048dcba027dfe6eb1
3
+ metadata.gz: 862e8133262fead707e4ca317b29d0e35425e3a7861ea1a52033bc91ba61bf6d
4
+ data.tar.gz: 5b2b32250d783fe58b0af54cc386f2568241644a0badc0b7247bb29b1ac94a93
5
5
  SHA512:
6
- metadata.gz: f2f11269c6a3a030231eeb93dfa6bee54b340ff5ad244df6d79074c95f111e3d2081f49f77756576cb8225640e8b8cad144884c8519bcf1b0e7bedea3ca1b00f
7
- data.tar.gz: 44ec06531632060b497cf1d02e6678c3d087ec3371cba86f53f9687848f73bb4e02c166b11d4db9e6b531b62ba2ca830649d71114063560f6dd764ca2ef10f07
6
+ metadata.gz: 2aab289f4f22b2f3a804ca7b0da4cf95e352a8d246611490d8d803edebbbc7e7c299355cd0b90e6f3ac8bc0d11e9bf3792a328c95847d32e1d984729afe66ed2
7
+ data.tar.gz: d9ec8ba4d314d099e909cdddf6dfb4c3c14b853b46f45c4909ac3ba10fb1880bd9a7b0465257fa91f9a4ea6c9f82723c16c177810ac15c89fab3790d7af31ad0
@@ -1,5 +1,19 @@
1
1
  # Unreleased
2
2
 
3
+ # 4.2.5
4
+
5
+ * Optimize the ruby connector write buffering. See #964.
6
+
7
+ # 4.2.4
8
+
9
+ * Fix bytesize calculations in the ruby connector, and work on a copy of the buffer. Fix #961, #962.
10
+
11
+ # 4.2.3
12
+
13
+ * Use io/wait instead of IO.select in the ruby connector. See #960.
14
+ * Use exception free non blocking IOs in the ruby connector. See #926.
15
+ * Prevent corruption of the client when an interrupt happen during inside a pipeline block. See #945.
16
+
3
17
  # 4.2.2
4
18
 
5
19
  * Fix `WATCH` support for `Redis::Distributed`. See #941.
data/README.md CHANGED
@@ -265,6 +265,7 @@ All timeout values are specified in seconds.
265
265
  When using pub/sub, you can subscribe to a channel using a timeout as well:
266
266
 
267
267
  ```ruby
268
+ redis = Redis.new(reconnect_attempts: 0)
268
269
  redis.subscribe_with_timeout(5, "news") do |on|
269
270
  on.message do |channel, message|
270
271
  # ...
@@ -2438,14 +2438,13 @@ class Redis
2438
2438
  end
2439
2439
 
2440
2440
  def pipelined
2441
- synchronize do |_client|
2441
+ synchronize do |prior_client|
2442
2442
  begin
2443
- pipeline = Pipeline.new(@client)
2444
- original, @client = @client, pipeline
2443
+ @client = Pipeline.new(prior_client)
2445
2444
  yield(self)
2446
- original.call_pipeline(@client)
2445
+ prior_client.call_pipeline(@client)
2447
2446
  ensure
2448
- @client = original
2447
+ @client = prior_client
2449
2448
  end
2450
2449
  end
2451
2450
  end
@@ -2481,17 +2480,16 @@ class Redis
2481
2480
  # @see #watch
2482
2481
  # @see #unwatch
2483
2482
  def multi
2484
- synchronize do |client|
2483
+ synchronize do |prior_client|
2485
2484
  if !block_given?
2486
- client.call([:multi])
2485
+ prior_client.call([:multi])
2487
2486
  else
2488
2487
  begin
2489
- pipeline = Pipeline::Multi.new(@client)
2490
- original, @client = @client, pipeline
2488
+ @client = Pipeline::Multi.new(prior_client)
2491
2489
  yield(self)
2492
- original.call_pipeline(pipeline)
2490
+ prior_client.call_pipeline(@client)
2493
2491
  ensure
2494
- @client = original
2492
+ @client = prior_client
2495
2493
  end
2496
2494
  end
2497
2495
  end
@@ -6,12 +6,16 @@ require "cgi"
6
6
 
7
7
  class Redis
8
8
  class Client
9
+ # Defaults are also used for converting string keys to symbols.
9
10
  DEFAULTS = {
10
11
  url: -> { ENV["REDIS_URL"] },
11
12
  scheme: "redis",
12
13
  host: "127.0.0.1",
13
14
  port: 6379,
14
15
  path: nil,
16
+ read_timeout: nil,
17
+ write_timeout: nil,
18
+ connect_timeout: nil,
15
19
  timeout: 5.0,
16
20
  password: nil,
17
21
  db: 0,
@@ -22,6 +26,7 @@ class Redis
22
26
  reconnect_delay: 0,
23
27
  reconnect_delay_max: 0.5,
24
28
  inherit_socket: false,
29
+ logger: nil,
25
30
  sentinels: nil,
26
31
  role: nil
27
32
  }.freeze
@@ -49,57 +49,50 @@ class Redis
49
49
  end
50
50
 
51
51
  def _read_from_socket(nbytes)
52
- begin
53
- read_nonblock(nbytes)
54
- rescue IO::WaitReadable
55
- if IO.select([self], nil, nil, @timeout)
56
- retry
57
- else
58
- raise Redis::TimeoutError
59
- end
60
- rescue IO::WaitWritable
61
- if IO.select(nil, [self], nil, @timeout)
62
- retry
63
- else
64
- raise Redis::TimeoutError
65
- end
66
- end
67
- rescue EOFError
68
- raise Errno::ECONNRESET
69
- end
70
-
71
- def _write_to_socket(data)
72
- begin
73
- write_nonblock(data)
74
- rescue IO::WaitWritable
75
- if IO.select(nil, [self], nil, @write_timeout)
76
- retry
77
- else
78
- raise Redis::TimeoutError
79
- end
80
- rescue IO::WaitReadable
81
- if IO.select([self], nil, nil, @write_timeout)
82
- retry
83
- else
84
- raise Redis::TimeoutError
52
+ loop do
53
+ case chunk = read_nonblock(nbytes, exception: false)
54
+ when :wait_readable
55
+ unless wait_readable(@timeout)
56
+ raise Redis::TimeoutError
57
+ end
58
+ when :wait_writable
59
+ unless wait_writable(@timeout)
60
+ raise Redis::TimeoutError
61
+ end
62
+ when nil
63
+ raise Errno::ECONNRESET
64
+ when String
65
+ return chunk
85
66
  end
86
67
  end
87
- rescue EOFError
88
- raise Errno::ECONNRESET
89
68
  end
90
69
 
91
- def write(data)
92
- return super(data) unless @write_timeout
70
+ def write(buffer)
71
+ return super(buffer) unless @write_timeout
93
72
 
94
- length = data.bytesize
95
- total_count = 0
73
+ bytes_to_write = buffer.bytesize
74
+ total_bytes_written = 0
96
75
  loop do
97
- count = _write_to_socket(data)
76
+ case bytes_written = write_nonblock(buffer, exception: false)
77
+ when :wait_readable
78
+ unless wait_readable(@write_timeout)
79
+ raise Redis::TimeoutError
80
+ end
81
+ when :wait_writable
82
+ unless wait_writable(@write_timeout)
83
+ raise Redis::TimeoutError
84
+ end
85
+ when nil
86
+ raise Errno::ECONNRESET
87
+ when Integer
88
+ total_bytes_written += bytes_written
98
89
 
99
- total_count += count
100
- return total_count if total_count >= length
90
+ if total_bytes_written >= bytes_to_write
91
+ return total_bytes_written
92
+ end
101
93
 
102
- data = data.byteslice(count..-1)
94
+ buffer = buffer.byteslice(bytes_written..-1)
95
+ end
103
96
  end
104
97
  end
105
98
  end
@@ -135,7 +128,7 @@ class Redis
135
128
  raise TimeoutError
136
129
  end
137
130
 
138
- # JRuby raises Errno::EAGAIN on #read_nonblock even when IO.select
131
+ # JRuby raises Errno::EAGAIN on #read_nonblock even when it
139
132
  # says it is readable (1.6.6, in both 1.8 and 1.9 mode).
140
133
  # Use the blocking #readpartial method instead.
141
134
 
@@ -160,7 +153,7 @@ class Redis
160
153
  begin
161
154
  sock.connect_nonblock(sockaddr)
162
155
  rescue Errno::EINPROGRESS
163
- raise TimeoutError if IO.select(nil, [sock], nil, timeout).nil?
156
+ raise TimeoutError unless sock.wait_writable(timeout)
164
157
 
165
158
  begin
166
159
  sock.connect_nonblock(sockaddr)
@@ -215,7 +208,7 @@ class Redis
215
208
  begin
216
209
  sock.connect_nonblock(sockaddr)
217
210
  rescue Errno::EINPROGRESS
218
- raise TimeoutError if IO.select(nil, [sock], nil, timeout).nil?
211
+ raise TimeoutError unless sock.wait_writable(timeout)
219
212
 
220
213
  begin
221
214
  sock.connect_nonblock(sockaddr)
@@ -233,6 +226,18 @@ class Redis
233
226
  class SSLSocket < ::OpenSSL::SSL::SSLSocket
234
227
  include SocketMixin
235
228
 
229
+ unless method_defined?(:wait_readable)
230
+ def wait_readable(timeout = nil)
231
+ to_io.wait_readable(timeout)
232
+ end
233
+ end
234
+
235
+ unless method_defined?(:wait_writable)
236
+ def wait_writable(timeout = nil)
237
+ to_io.wait_writable(timeout)
238
+ end
239
+ end
240
+
236
241
  def self.connect(host, port, timeout, ssl_params)
237
242
  # Note: this is using Redis::Connection::TCPSocket
238
243
  tcp_sock = TCPSocket.connect(host, port, timeout)
@@ -254,13 +259,13 @@ class Redis
254
259
  # Instead, you have to retry.
255
260
  ssl_sock.connect_nonblock
256
261
  rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable
257
- if IO.select([ssl_sock], nil, nil, timeout)
262
+ if ssl_sock.wait_readable(timeout)
258
263
  retry
259
264
  else
260
265
  raise TimeoutError
261
266
  end
262
267
  rescue IO::WaitWritable
263
- if IO.select(nil, [ssl_sock], nil, timeout)
268
+ if ssl_sock.wait_writable(timeout)
264
269
  retry
265
270
  else
266
271
  raise TimeoutError
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Redis
4
- VERSION = '4.2.2'
4
+ VERSION = '4.2.5'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.2
4
+ version: 4.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2020-09-07 00:00:00.000000000 Z
19
+ date: 2020-11-20 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: em-synchrony
@@ -102,9 +102,9 @@ licenses:
102
102
  metadata:
103
103
  bug_tracker_uri: https://github.com/redis/redis-rb/issues
104
104
  changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
105
- documentation_uri: https://www.rubydoc.info/gems/redis/4.2.2
105
+ documentation_uri: https://www.rubydoc.info/gems/redis/4.2.5
106
106
  homepage_uri: https://github.com/redis/redis-rb
107
- source_code_uri: https://github.com/redis/redis-rb/tree/v4.2.2
107
+ source_code_uri: https://github.com/redis/redis-rb/tree/v4.2.5
108
108
  post_install_message:
109
109
  rdoc_options: []
110
110
  require_paths: