redis 4.2.2 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28eb23d20152436fc47f334f517c6fa62855e8e4711b44979cb05d86f8dcdd34
4
- data.tar.gz: 46d01b3f5539800142582aeb7ebeabe4327bce970e31ce2048dcba027dfe6eb1
3
+ metadata.gz: 416a2f007042c19453c13361aa4440a507e47fb32c28adc68e7c574c6651f5b4
4
+ data.tar.gz: 1a845f2af649d64f8b274962c9d5d10e6eb5d046474b6e44288676432fe8a98b
5
5
  SHA512:
6
- metadata.gz: f2f11269c6a3a030231eeb93dfa6bee54b340ff5ad244df6d79074c95f111e3d2081f49f77756576cb8225640e8b8cad144884c8519bcf1b0e7bedea3ca1b00f
7
- data.tar.gz: 44ec06531632060b497cf1d02e6678c3d087ec3371cba86f53f9687848f73bb4e02c166b11d4db9e6b531b62ba2ca830649d71114063560f6dd764ca2ef10f07
6
+ metadata.gz: 3766992242ae284ca474bc8564c6760de88e635a8c3bc3c80da08062d698cc891bf00455b5d98768709ecc766f8ad305fe03cc5806f03fda3ebb93049e0a1cce
7
+ data.tar.gz: f440c984ec58ff091a6a696952239cb04cf145752b485543e5da7215a327b40be4391b3fe6ca67753f84ec43913b9d90ec0b6f812e1696890a7c17cbf3aa3630
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Unreleased
2
2
 
3
+ # 4.3.1
4
+
5
+ * Fix password authentication against redis server 5 and older.
6
+
7
+ # 4.3.0
8
+
9
+ * Add the TYPE argument to scan and scan_each. See #985.
10
+ * Support AUTH command for ACL. See #967.
11
+
12
+ # 4.2.5
13
+
14
+ * Optimize the ruby connector write buffering. See #964.
15
+
16
+ # 4.2.4
17
+
18
+ * Fix bytesize calculations in the ruby connector, and work on a copy of the buffer. Fix #961, #962.
19
+
20
+ # 4.2.3
21
+
22
+ * Use io/wait instead of IO.select in the ruby connector. See #960.
23
+ * Use exception free non blocking IOs in the ruby connector. See #926.
24
+ * Prevent corruption of the client when an interrupt happen during inside a pipeline block. See #945.
25
+
3
26
  # 4.2.2
4
27
 
5
28
  * Fix `WATCH` support for `Redis::Distributed`. See #941.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # redis-rb [![Build Status][travis-image]][travis-link] [![Inline docs][inchpages-image]][inchpages-link] ![](https://github.com/redis/redis-rb/workflows/Test/badge.svg?branch=master)
1
+ # redis-rb [![Build Status][gh-actions-image]][gh-actions-link] [![Inline docs][inchpages-image]][inchpages-link]
2
2
 
3
3
  A Ruby client that tries to match [Redis][redis-home]' API one-to-one, while still
4
4
  providing an idiomatic interface.
@@ -54,6 +54,12 @@ To connect to a password protected Redis instance, use:
54
54
  redis = Redis.new(password: "mysecret")
55
55
  ```
56
56
 
57
+ To connect a Redis instance using [ACL](https://redis.io/topics/acl), use:
58
+
59
+ ```ruby
60
+ redis = Redis.new(username: 'myname', password: 'mysecret')
61
+ ```
62
+
57
63
  The Redis class exports methods that are named identical to the commands
58
64
  they execute. The arguments these methods accept are often identical to
59
65
  the arguments specified on the [Redis website][redis-commands]. For
@@ -265,6 +271,7 @@ All timeout values are specified in seconds.
265
271
  When using pub/sub, you can subscribe to a channel using a timeout as well:
266
272
 
267
273
  ```ruby
274
+ redis = Redis.new(reconnect_attempts: 0)
268
275
  redis.subscribe_with_timeout(5, "news") do |on|
269
276
  on.message do |channel, message|
270
277
  # ...
@@ -439,7 +446,7 @@ redis = Redis.new(:driver => :synchrony)
439
446
  ## Testing
440
447
 
441
448
  This library is tested against recent Ruby and Redis versions.
442
- Check [Travis][travis-link] for the exact versions supported.
449
+ Check [Github Actions][gh-actions-link] for the exact versions supported.
443
450
 
444
451
  ## See Also
445
452
 
@@ -458,12 +465,11 @@ client and evangelized Redis in Rubyland. Thank you, Ezra.
458
465
  requests.
459
466
 
460
467
 
461
- [inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg
462
- [inchpages-link]: https://inch-ci.org/github/redis/redis-rb
463
- [redis-commands]: https://redis.io/commands
464
- [redis-home]: https://redis.io
465
- [redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis
466
- [travis-home]: https://travis-ci.org/
467
- [travis-image]: https://secure.travis-ci.org/redis/redis-rb.svg?branch=master
468
- [travis-link]: https://travis-ci.org/redis/redis-rb
469
- [rubydoc]: http://www.rubydoc.info/gems/redis
468
+ [inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg
469
+ [inchpages-link]: https://inch-ci.org/github/redis/redis-rb
470
+ [redis-commands]: https://redis.io/commands
471
+ [redis-home]: https://redis.io
472
+ [redis-url]: http://www.iana.org/assignments/uri-schemes/prov/redis
473
+ [gh-actions-image]: https://github.com/redis/redis-rb/workflows/Test/badge.svg
474
+ [gh-actions-link]: https://github.com/redis/redis-rb/actions
475
+ [rubydoc]: http://www.rubydoc.info/gems/redis
data/lib/redis.rb CHANGED
@@ -39,6 +39,7 @@ class Redis
39
39
  # @option options [String] :path path to server socket (overrides host and port)
40
40
  # @option options [Float] :timeout (5.0) timeout in seconds
41
41
  # @option options [Float] :connect_timeout (same as timeout) timeout for initial connect in seconds
42
+ # @option options [String] :username Username to authenticate against server
42
43
  # @option options [String] :password Password to authenticate against server
43
44
  # @option options [Integer] :db (0) Database to select after initial connect
44
45
  # @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`, `:synchrony`
@@ -143,12 +144,13 @@ class Redis
143
144
 
144
145
  # Authenticate to the server.
145
146
  #
146
- # @param [String] password must match the password specified in the
147
- # `requirepass` directive in the configuration file
147
+ # @param [Array<String>] args includes both username and password
148
+ # or only password
148
149
  # @return [String] `OK`
149
- def auth(password)
150
+ # @see https://redis.io/commands/auth AUTH command
151
+ def auth(*args)
150
152
  synchronize do |client|
151
- client.call([:auth, password])
153
+ client.call([:auth, *args])
152
154
  end
153
155
  end
154
156
 
@@ -1170,23 +1172,29 @@ class Redis
1170
1172
  end
1171
1173
  end
1172
1174
 
1173
- # Remove and get the first element in a list.
1175
+ # Remove and get the first elements in a list.
1174
1176
  #
1175
1177
  # @param [String] key
1176
- # @return [String]
1177
- def lpop(key)
1178
+ # @param [Integer] count number of elements to remove
1179
+ # @return [String, Array<String>] the values of the first elements
1180
+ def lpop(key, count = nil)
1178
1181
  synchronize do |client|
1179
- client.call([:lpop, key])
1182
+ command = [:lpop, key]
1183
+ command << count if count
1184
+ client.call(command)
1180
1185
  end
1181
1186
  end
1182
1187
 
1183
- # Remove and get the last element in a list.
1188
+ # Remove and get the last elements in a list.
1184
1189
  #
1185
1190
  # @param [String] key
1186
- # @return [String]
1187
- def rpop(key)
1191
+ # @param [Integer] count number of elements to remove
1192
+ # @return [String, Array<String>] the values of the last elements
1193
+ def rpop(key, count = nil)
1188
1194
  synchronize do |client|
1189
- client.call([:rpop, key])
1195
+ command = [:rpop, key]
1196
+ command << count if count
1197
+ client.call(command)
1190
1198
  end
1191
1199
  end
1192
1200
 
@@ -2438,14 +2446,13 @@ class Redis
2438
2446
  end
2439
2447
 
2440
2448
  def pipelined
2441
- synchronize do |_client|
2449
+ synchronize do |prior_client|
2442
2450
  begin
2443
- pipeline = Pipeline.new(@client)
2444
- original, @client = @client, pipeline
2451
+ @client = Pipeline.new(prior_client)
2445
2452
  yield(self)
2446
- original.call_pipeline(@client)
2453
+ prior_client.call_pipeline(@client)
2447
2454
  ensure
2448
- @client = original
2455
+ @client = prior_client
2449
2456
  end
2450
2457
  end
2451
2458
  end
@@ -2481,17 +2488,16 @@ class Redis
2481
2488
  # @see #watch
2482
2489
  # @see #unwatch
2483
2490
  def multi
2484
- synchronize do |client|
2491
+ synchronize do |prior_client|
2485
2492
  if !block_given?
2486
- client.call([:multi])
2493
+ prior_client.call([:multi])
2487
2494
  else
2488
2495
  begin
2489
- pipeline = Pipeline::Multi.new(@client)
2490
- original, @client = @client, pipeline
2496
+ @client = Pipeline::Multi.new(prior_client)
2491
2497
  yield(self)
2492
- original.call_pipeline(pipeline)
2498
+ prior_client.call_pipeline(@client)
2493
2499
  ensure
2494
- @client = original
2500
+ @client = prior_client
2495
2501
  end
2496
2502
  end
2497
2503
  end
@@ -2638,12 +2644,13 @@ class Redis
2638
2644
  _eval(:evalsha, args)
2639
2645
  end
2640
2646
 
2641
- def _scan(command, cursor, args, match: nil, count: nil, &block)
2647
+ def _scan(command, cursor, args, match: nil, count: nil, type: nil, &block)
2642
2648
  # SSCAN/ZSCAN/HSCAN already prepend the key to +args+.
2643
2649
 
2644
2650
  args << cursor
2645
2651
  args << "MATCH" << match if match
2646
2652
  args << "COUNT" << count if count
2653
+ args << "TYPE" << type if type
2647
2654
 
2648
2655
  synchronize do |client|
2649
2656
  client.call([command] + args, &block)
@@ -2658,11 +2665,15 @@ class Redis
2658
2665
  # @example Retrieve a batch of keys matching a pattern
2659
2666
  # redis.scan(4, :match => "key:1?")
2660
2667
  # # => ["92", ["key:13", "key:18"]]
2668
+ # @example Retrieve a batch of keys of a certain type
2669
+ # redis.scan(92, :type => "zset")
2670
+ # # => ["173", ["sortedset:14", "sortedset:78"]]
2661
2671
  #
2662
2672
  # @param [String, Integer] cursor the cursor of the iteration
2663
2673
  # @param [Hash] options
2664
2674
  # - `:match => String`: only return keys matching the pattern
2665
2675
  # - `:count => Integer`: return count keys at most per iteration
2676
+ # - `:type => String`: return keys only of the given type
2666
2677
  #
2667
2678
  # @return [String, Array<String>] the next cursor and all found keys
2668
2679
  def scan(cursor, **options)
@@ -2678,10 +2689,15 @@ class Redis
2678
2689
  # redis.scan_each(:match => "key:1?") {|key| puts key}
2679
2690
  # # => key:13
2680
2691
  # # => key:18
2692
+ # @example Execute block for each key of a type
2693
+ # redis.scan_each(:type => "hash") {|key| puts redis.type(key)}
2694
+ # # => "hash"
2695
+ # # => "hash"
2681
2696
  #
2682
2697
  # @param [Hash] options
2683
2698
  # - `:match => String`: only return keys matching the pattern
2684
2699
  # - `:count => Integer`: return count keys at most per iteration
2700
+ # - `:type => String`: return keys only of the given type
2685
2701
  #
2686
2702
  # @return [Enumerator] an enumerator for all found keys
2687
2703
  def scan_each(**options, &block)
data/lib/redis/client.rb CHANGED
@@ -6,13 +6,18 @@ 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,
20
+ username: nil,
16
21
  password: nil,
17
22
  db: 0,
18
23
  driver: nil,
@@ -22,6 +27,7 @@ class Redis
22
27
  reconnect_delay: 0,
23
28
  reconnect_delay_max: 0.5,
24
29
  inherit_socket: false,
30
+ logger: nil,
25
31
  sentinels: nil,
26
32
  role: nil
27
33
  }.freeze
@@ -56,6 +62,10 @@ class Redis
56
62
  @options[:read_timeout]
57
63
  end
58
64
 
65
+ def username
66
+ @options[:username]
67
+ end
68
+
59
69
  def password
60
70
  @options[:password]
61
71
  end
@@ -105,7 +115,17 @@ class Redis
105
115
  # Don't try to reconnect when the connection is fresh
106
116
  with_reconnect(false) do
107
117
  establish_connection
108
- call [:auth, password] if password
118
+ if password
119
+ if username
120
+ begin
121
+ call [:auth, username, password]
122
+ rescue CommandError # Likely on Redis < 6
123
+ call [:auth, password]
124
+ end
125
+ else
126
+ call [:auth, password]
127
+ end
128
+ end
109
129
  call [:select, db] if db != 0
110
130
  call [:client, :setname, @options[:id]] if @options[:id]
111
131
  @connector.check(self)
@@ -126,7 +146,7 @@ class Redis
126
146
  reply = process([command]) { read }
127
147
  raise reply if reply.is_a?(CommandError)
128
148
 
129
- if block_given?
149
+ if block_given? && reply != 'QUEUED'
130
150
  yield reply
131
151
  else
132
152
  reply
@@ -429,7 +449,8 @@ class Redis
429
449
  defaults[:scheme] = uri.scheme
430
450
  defaults[:host] = uri.host if uri.host
431
451
  defaults[:port] = uri.port if uri.port
432
- defaults[:password] = CGI.unescape(uri.password) if uri.password
452
+ defaults[:username] = CGI.unescape(uri.user) if uri.user && !uri.user.empty?
453
+ defaults[:password] = CGI.unescape(uri.password) if uri.password && !uri.password.empty?
433
454
  defaults[:db] = uri.path[1..-1].to_i if uri.path
434
455
  defaults[:role] = :master
435
456
  else
@@ -505,7 +526,7 @@ class Redis
505
526
  require_relative "connection/#{driver}"
506
527
  rescue LoadError, NameError
507
528
  begin
508
- require "connection/#{driver}"
529
+ require "redis/connection/#{driver}"
509
530
  rescue LoadError, NameError => error
510
531
  raise "Cannot load driver #{driver.inspect}: #{error.message}"
511
532
  end
@@ -574,6 +595,7 @@ class Redis
574
595
  client = Client.new(@options.merge({
575
596
  host: sentinel[:host] || sentinel["host"],
576
597
  port: sentinel[:port] || sentinel["port"],
598
+ username: sentinel[:username] || sentinel["username"],
577
599
  password: sentinel[:password] || sentinel["password"],
578
600
  reconnect_attempts: 0
579
601
  }))
data/lib/redis/cluster.rb CHANGED
@@ -128,7 +128,7 @@ class Redis
128
128
  def send_command(command, &block)
129
129
  cmd = command.first.to_s.downcase
130
130
  case cmd
131
- when 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
131
+ when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
132
132
  @node.call_all(command, &block).first
133
133
  when 'flushall', 'flushdb'
134
134
  @node.call_master(command, &block).first
@@ -18,6 +18,7 @@ class Redis
18
18
  @node_opts = build_node_options(node_addrs)
19
19
  @replica = options.delete(:replica) == true
20
20
  add_common_node_option_if_needed(options, @node_opts, :scheme)
21
+ add_common_node_option_if_needed(options, @node_opts, :username)
21
22
  add_common_node_option_if_needed(options, @node_opts, :password)
22
23
  @options = options
23
24
  end
@@ -63,7 +64,9 @@ class Redis
63
64
  raise InvalidClientOptionError, "Invalid uri scheme #{addr}" unless VALID_SCHEMES.include?(uri.scheme)
64
65
 
65
66
  db = uri.path.split('/')[1]&.to_i
66
- { scheme: uri.scheme, password: uri.password, host: uri.host, port: uri.port, db: db }.reject { |_, v| v.nil? }
67
+
68
+ { scheme: uri.scheme, username: uri.user, password: uri.password, host: uri.host, port: uri.port, db: db }
69
+ .reject { |_, v| v.nil? || v == '' }
67
70
  rescue URI::InvalidURIError => err
68
71
  raise InvalidClientOptionError, err.message
69
72
  end
@@ -79,7 +82,7 @@ class Redis
79
82
 
80
83
  # Redis cluster node returns only host and port information.
81
84
  # So we should complement additional information such as:
82
- # scheme, password and so on.
85
+ # scheme, username, password and so on.
83
86
  def add_common_node_option_if_needed(options, node_opts, key)
84
87
  return options if options[key].nil? && node_opts.first[key].nil?
85
88
 
@@ -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
@@ -413,14 +413,14 @@ class Redis
413
413
  node_for(key).rpushx(key, value)
414
414
  end
415
415
 
416
- # Remove and get the first element in a list.
417
- def lpop(key)
418
- node_for(key).lpop(key)
416
+ # Remove and get the first elements in a list.
417
+ def lpop(key, count = nil)
418
+ node_for(key).lpop(key, count)
419
419
  end
420
420
 
421
- # Remove and get the last element in a list.
422
- def rpop(key)
423
- node_for(key).rpop(key)
421
+ # Remove and get the last elements in a list.
422
+ def rpop(key, count = nil)
423
+ node_for(key).rpop(key, count)
424
424
  end
425
425
 
426
426
  # Remove the last element in a list, append it to another list and return
data/lib/redis/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Redis
4
- VERSION = '4.2.2'
4
+ VERSION = '4.3.1'
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.3.1
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: 2021-06-11 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.3.1
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.3.1
108
108
  post_install_message:
109
109
  rdoc_options: []
110
110
  require_paths: