redis 4.1.4 → 4.2.5

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: 83f1f7270db68603d63e86ec43e68348cb5ccb2b4e6759642d89898566bdbaf6
4
- data.tar.gz: 45c5bcc92629ec7d85cdc2b913e7922cd5425f2e6691891efc379aeec73026b3
3
+ metadata.gz: 862e8133262fead707e4ca317b29d0e35425e3a7861ea1a52033bc91ba61bf6d
4
+ data.tar.gz: 5b2b32250d783fe58b0af54cc386f2568241644a0badc0b7247bb29b1ac94a93
5
5
  SHA512:
6
- metadata.gz: 692dfc5c73c6410492589f38f279976a023f6a2ff13f7b1476806011eb387f41bed784bdeac746de5f4b990b6d22bf297b36dddc7b8e448a842241a389f50796
7
- data.tar.gz: 55a9e305c7563f5dd7d38f50dc7b919967dbb0f6a131ebc5e1569f49f196ab458203b6594394fa9a33ea9e337b741113e781378113783683dd36b87196607b8f
6
+ metadata.gz: 2aab289f4f22b2f3a804ca7b0da4cf95e352a8d246611490d8d803edebbbc7e7c299355cd0b90e6f3ac8bc0d11e9bf3792a328c95847d32e1d984729afe66ed2
7
+ data.tar.gz: d9ec8ba4d314d099e909cdddf6dfb4c3c14b853b46f45c4909ac3ba10fb1880bd9a7b0465257fa91f9a4ea6c9f82723c16c177810ac15c89fab3790d7af31ad0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
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
+
17
+ # 4.2.2
18
+
19
+ * Fix `WATCH` support for `Redis::Distributed`. See #941.
20
+ * Fix handling of empty stream responses. See #905, #929.
21
+
22
+ # 4.2.1
23
+
24
+ * Fix `exists?` returning an actual boolean when called with multiple keys. See #918.
25
+ * Setting `Redis.exists_returns_integer = false` disables warning message about new behaviour. See #920.
26
+
27
+ # 4.2.0
28
+
29
+ * Convert commands to accept keyword arguments rather than option hashes. This both help catching typos, and reduce needless allocations.
30
+ * Deprecate the synchrony driver. It will be removed in 5.0 and hopefully maintained as a separate gem. See #915.
31
+ * Make `Redis#exists` variadic, will return an Integer if called with multiple keys.
32
+ * Add `Redis#exists?` to get a Boolean if any of the keys exists.
33
+ * `Redis#exists` when called with a single key will warn that future versions will return an Integer.
34
+ Set `Redis.exists_returns_integer = true` to opt-in to the new behavior.
35
+ * Support `keepttl` ooption in `set`. See #913.
36
+ * Optimized initialization of Redis::Cluster. See #912.
37
+ * Accept sentinel options even with string key. See #599.
38
+ * Verify TLS connections by default. See #900.
39
+ * Make `Redis#hset` variadic. It now returns an integer, not a boolean. See #910.
40
+
3
41
  # 4.1.4
4
42
 
5
43
  * Alias `Redis#disconnect` as `#close`. See #901.
@@ -9,6 +47,7 @@
9
47
  * Increase buffer size in the ruby connector. See #880.
10
48
  * Fix thread safety of `Redis.queue`. See #878.
11
49
  * Deprecate `Redis::Future#==` as it's likely to be a mistake. See #876.
50
+ * Support `KEEPTTL` option for SET command. See #913.
12
51
 
13
52
  # 4.1.3
14
53
 
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  A Ruby client that tries to match [Redis][redis-home]' API one-to-one, while still
4
4
  providing an idiomatic interface.
5
5
 
6
+ See [RubyDoc.info][rubydoc] for the API docs of the latest published gem.
6
7
 
7
8
  ## Getting started
8
9
 
@@ -34,6 +35,9 @@ You can also specify connection options as a [`redis://` URL][redis-url]:
34
35
  redis = Redis.new(url: "redis://:p4ssw0rd@10.0.1.1:6380/15")
35
36
  ```
36
37
 
38
+ The client expects passwords with special chracters to be URL-encoded (i.e.
39
+ `CGI.escape(password)`).
40
+
37
41
  By default, the client will try to read the `REDIS_URL` environment variable
38
42
  and use that as URL to connect to. The above statement is therefore equivalent
39
43
  to setting this environment variable and calling `Redis.new` without arguments.
@@ -147,8 +151,8 @@ redis.mget('{key}1', '{key}2')
147
151
 
148
152
  ## Storing objects
149
153
 
150
- Redis only stores strings as values. If you want to store an object, you
151
- can use a serialization mechanism such as JSON:
154
+ Redis "string" types can be used to store serialized Ruby objects, for
155
+ example with JSON:
152
156
 
153
157
  ```ruby
154
158
  require "json"
@@ -261,6 +265,7 @@ All timeout values are specified in seconds.
261
265
  When using pub/sub, you can subscribe to a channel using a timeout as well:
262
266
 
263
267
  ```ruby
268
+ redis = Redis.new(reconnect_attempts: 0)
264
269
  redis.subscribe_with_timeout(5, "news") do |on|
265
270
  on.message do |channel, message|
266
271
  # ...
@@ -322,7 +327,7 @@ This library supports natively terminating client side SSL/TLS connections
322
327
  when talking to Redis via a server-side proxy such as [stunnel], [hitch],
323
328
  or [ghostunnel].
324
329
 
325
- To enable SSL support, pass the `:ssl => :true` option when configuring the
330
+ To enable SSL support, pass the `:ssl => true` option when configuring the
326
331
  Redis client, or pass in `:url => "rediss://..."` (like HTTPS for Redis).
327
332
  You will also need to pass in an `:ssl_params => { ... }` hash used to
328
333
  configure the `OpenSSL::SSL::SSLContext` object used for the connection:
@@ -451,7 +456,7 @@ client and evangelized Redis in Rubyland. Thank you, Ezra.
451
456
  ## Contributing
452
457
 
453
458
  [Fork the project](https://github.com/redis/redis-rb) and send pull
454
- requests. You can also ask for help at `#redis-rb` on Freenode.
459
+ requests.
455
460
 
456
461
 
457
462
  [inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg
data/lib/redis/client.rb CHANGED
@@ -6,24 +6,30 @@ require "cgi"
6
6
 
7
7
  class Redis
8
8
  class Client
9
-
9
+ # Defaults are also used for converting string keys to symbols.
10
10
  DEFAULTS = {
11
- :url => lambda { ENV["REDIS_URL"] },
12
- :scheme => "redis",
13
- :host => "127.0.0.1",
14
- :port => 6379,
15
- :path => nil,
16
- :timeout => 5.0,
17
- :password => nil,
18
- :db => 0,
19
- :driver => nil,
20
- :id => nil,
21
- :tcp_keepalive => 0,
22
- :reconnect_attempts => 1,
23
- :reconnect_delay => 0,
24
- :reconnect_delay_max => 0.5,
25
- :inherit_socket => false
26
- }
11
+ url: -> { ENV["REDIS_URL"] },
12
+ scheme: "redis",
13
+ host: "127.0.0.1",
14
+ port: 6379,
15
+ path: nil,
16
+ read_timeout: nil,
17
+ write_timeout: nil,
18
+ connect_timeout: nil,
19
+ timeout: 5.0,
20
+ password: nil,
21
+ db: 0,
22
+ driver: nil,
23
+ id: nil,
24
+ tcp_keepalive: 0,
25
+ reconnect_attempts: 1,
26
+ reconnect_delay: 0,
27
+ reconnect_delay_max: 0.5,
28
+ inherit_socket: false,
29
+ logger: nil,
30
+ sentinels: nil,
31
+ role: nil
32
+ }.freeze
27
33
 
28
34
  attr_reader :options
29
35
 
@@ -89,7 +95,7 @@ class Redis
89
95
  @pending_reads = 0
90
96
 
91
97
  @connector =
92
- if options.include?(:sentinels)
98
+ if !@options[:sentinels].nil?
93
99
  Connector::Sentinel.new(@options)
94
100
  elsif options.include?(:connector) && options[:connector].respond_to?(:new)
95
101
  options.delete(:connector).new(@options)
@@ -166,6 +172,7 @@ class Redis
166
172
  end
167
173
  rescue ConnectionError => e
168
174
  return nil if pipeline.shutdown?
175
+
169
176
  # Assume the pipeline was sent in one piece, but execution of
170
177
  # SHUTDOWN caused none of the replies for commands that were executed
171
178
  # prior to it from coming back around.
@@ -244,13 +251,13 @@ class Redis
244
251
  end
245
252
 
246
253
  def connected?
247
- !! (connection && connection.connected?)
254
+ !!(connection && connection.connected?)
248
255
  end
249
256
 
250
257
  def disconnect
251
258
  connection.disconnect if connected?
252
259
  end
253
- alias_method :close, :disconnect
260
+ alias close disconnect
254
261
 
255
262
  def reconnect
256
263
  disconnect
@@ -301,30 +308,27 @@ class Redis
301
308
  with_socket_timeout(0, &blk)
302
309
  end
303
310
 
304
- def with_reconnect(val=true)
305
- begin
306
- original, @reconnect = @reconnect, val
307
- yield
308
- ensure
309
- @reconnect = original
310
- end
311
+ def with_reconnect(val = true)
312
+ original, @reconnect = @reconnect, val
313
+ yield
314
+ ensure
315
+ @reconnect = original
311
316
  end
312
317
 
313
318
  def without_reconnect(&blk)
314
319
  with_reconnect(false, &blk)
315
320
  end
316
321
 
317
- protected
322
+ protected
318
323
 
319
324
  def logging(commands)
320
- return yield unless @logger && @logger.debug?
325
+ return yield unless @logger&.debug?
321
326
 
322
327
  begin
323
328
  commands.each do |name, *args|
324
329
  logged_args = args.map do |a|
325
- case
326
- when a.respond_to?(:inspect) then a.inspect
327
- when a.respond_to?(:to_s) then a.to_s
330
+ if a.respond_to?(:inspect) then a.inspect
331
+ elsif a.respond_to?(:to_s) then a.to_s
328
332
  else
329
333
  # handle poorly-behaved descendants of BasicObject
330
334
  klass = a.instance_exec { (class << self; self end).superclass }
@@ -358,9 +362,9 @@ class Redis
358
362
  Errno::ENETUNREACH,
359
363
  Errno::ENOENT,
360
364
  Errno::ETIMEDOUT,
361
- Errno::EINVAL
365
+ Errno::EINVAL => error
362
366
 
363
- raise CannotConnectError, "Error connecting to Redis on #{location} (#{$!.class})"
367
+ raise CannotConnectError, "Error connecting to Redis on #{location} (#{error.class})"
364
368
  end
365
369
 
366
370
  def ensure_connected
@@ -374,9 +378,9 @@ class Redis
374
378
  if connected?
375
379
  unless inherit_socket? || Process.pid == @pid
376
380
  raise InheritedError,
377
- "Tried to use a connection from a child process without reconnecting. " +
378
- "You need to reconnect to Redis after forking " +
379
- "or set :inherit_socket to true."
381
+ "Tried to use a connection from a child process without reconnecting. " \
382
+ "You need to reconnect to Redis after forking " \
383
+ "or set :inherit_socket to true."
380
384
  end
381
385
  else
382
386
  connect
@@ -387,7 +391,7 @@ class Redis
387
391
  disconnect
388
392
 
389
393
  if attempts <= @options[:reconnect_attempts] && @reconnect
390
- sleep_t = [(@options[:reconnect_delay] * 2**(attempts-1)),
394
+ sleep_t = [(@options[:reconnect_delay] * 2**(attempts - 1)),
391
395
  @options[:reconnect_delay_max]].min
392
396
 
393
397
  Kernel.sleep(sleep_t)
@@ -409,16 +413,14 @@ class Redis
409
413
 
410
414
  defaults.keys.each do |key|
411
415
  # Fill in defaults if needed
412
- if defaults[key].respond_to?(:call)
413
- defaults[key] = defaults[key].call
414
- end
416
+ defaults[key] = defaults[key].call if defaults[key].respond_to?(:call)
415
417
 
416
418
  # Symbolize only keys that are needed
417
- options[key] = options[key.to_s] if options.has_key?(key.to_s)
419
+ options[key] = options[key.to_s] if options.key?(key.to_s)
418
420
  end
419
421
 
420
422
  url = options[:url]
421
- url = defaults[:url] if url == nil
423
+ url = defaults[:url] if url.nil?
422
424
 
423
425
  # Override defaults from URL if given
424
426
  if url
@@ -427,7 +429,7 @@ class Redis
427
429
  uri = URI(url)
428
430
 
429
431
  if uri.scheme == "unix"
430
- defaults[:path] = uri.path
432
+ defaults[:path] = uri.path
431
433
  elsif uri.scheme == "redis" || uri.scheme == "rediss"
432
434
  defaults[:scheme] = uri.scheme
433
435
  defaults[:host] = uri.host if uri.host
@@ -458,7 +460,7 @@ class Redis
458
460
  options[:port] = options[:port].to_i
459
461
  end
460
462
 
461
- if options.has_key?(:timeout)
463
+ if options.key?(:timeout)
462
464
  options[:connect_timeout] ||= options[:timeout]
463
465
  options[:read_timeout] ||= options[:timeout]
464
466
  options[:write_timeout] ||= options[:timeout]
@@ -477,7 +479,7 @@ class Redis
477
479
 
478
480
  case options[:tcp_keepalive]
479
481
  when Hash
480
- [:time, :intvl, :probes].each do |key|
482
+ %i[time intvl probes].each do |key|
481
483
  unless options[:tcp_keepalive][key].is_a?(Integer)
482
484
  raise "Expected the #{key.inspect} key in :tcp_keepalive to be an Integer"
483
485
  end
@@ -485,13 +487,13 @@ class Redis
485
487
 
486
488
  when Integer
487
489
  if options[:tcp_keepalive] >= 60
488
- options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 20, :intvl => 10, :probes => 2}
490
+ options[:tcp_keepalive] = { time: options[:tcp_keepalive] - 20, intvl: 10, probes: 2 }
489
491
 
490
492
  elsif options[:tcp_keepalive] >= 30
491
- options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 10, :intvl => 5, :probes => 2}
493
+ options[:tcp_keepalive] = { time: options[:tcp_keepalive] - 10, intvl: 5, probes: 2 }
492
494
 
493
495
  elsif options[:tcp_keepalive] >= 5
494
- options[:tcp_keepalive] = {:time => options[:tcp_keepalive] - 2, :intvl => 2, :probes => 1}
496
+ options[:tcp_keepalive] = { time: options[:tcp_keepalive] - 2, intvl: 2, probes: 1 }
495
497
  end
496
498
  end
497
499
 
@@ -503,14 +505,14 @@ class Redis
503
505
  def _parse_driver(driver)
504
506
  driver = driver.to_s if driver.is_a?(Symbol)
505
507
 
506
- if driver.kind_of?(String)
508
+ if driver.is_a?(String)
507
509
  begin
508
510
  require_relative "connection/#{driver}"
509
- rescue LoadError, NameError => e
511
+ rescue LoadError, NameError
510
512
  begin
511
513
  require "connection/#{driver}"
512
- rescue LoadError, NameError => e
513
- raise RuntimeError, "Cannot load driver #{driver.inspect}: #{e.message}"
514
+ rescue LoadError, NameError => error
515
+ raise "Cannot load driver #{driver.inspect}: #{error.message}"
514
516
  end
515
517
  end
516
518
 
@@ -529,8 +531,7 @@ class Redis
529
531
  @options
530
532
  end
531
533
 
532
- def check(client)
533
- end
534
+ def check(client); end
534
535
 
535
536
  class Sentinel < Connector
536
537
  def initialize(options)
@@ -539,7 +540,7 @@ class Redis
539
540
  @options[:db] = DEFAULTS.fetch(:db)
540
541
 
541
542
  @sentinels = @options.delete(:sentinels).dup
542
- @role = @options.fetch(:role, "master").to_s
543
+ @role = (@options[:role] || "master").to_s
543
544
  @master = @options[:host]
544
545
  end
545
546
 
@@ -562,13 +563,13 @@ class Redis
562
563
 
563
564
  def resolve
564
565
  result = case @role
565
- when "master"
566
- resolve_master
567
- when "slave"
568
- resolve_slave
569
- else
570
- raise ArgumentError, "Unknown instance role #{@role}"
571
- end
566
+ when "master"
567
+ resolve_master
568
+ when "slave"
569
+ resolve_slave
570
+ else
571
+ raise ArgumentError, "Unknown instance role #{@role}"
572
+ end
572
573
 
573
574
  result || (raise ConnectionError, "Unable to fetch #{@role} via Sentinel.")
574
575
  end
@@ -576,11 +577,11 @@ class Redis
576
577
  def sentinel_detect
577
578
  @sentinels.each do |sentinel|
578
579
  client = Client.new(@options.merge({
579
- :host => sentinel[:host],
580
- :port => sentinel[:port],
581
- password: sentinel[:password],
582
- :reconnect_attempts => 0,
583
- }))
580
+ host: sentinel[:host] || sentinel["host"],
581
+ port: sentinel[:port] || sentinel["port"],
582
+ password: sentinel[:password] || sentinel["password"],
583
+ reconnect_attempts: 0
584
+ }))
584
585
 
585
586
  begin
586
587
  if result = yield(client)
@@ -602,7 +603,7 @@ class Redis
602
603
  def resolve_master
603
604
  sentinel_detect do |client|
604
605
  if reply = client.call(["sentinel", "get-master-addr-by-name", @master])
605
- {:host => reply[0], :port => reply[1]}
606
+ { host: reply[0], port: reply[1] }
606
607
  end
607
608
  end
608
609
  end
@@ -620,7 +621,7 @@ class Redis
620
621
  slave = slaves.sample
621
622
  {
622
623
  host: slave.fetch('ip'),
623
- port: slave.fetch('port'),
624
+ port: slave.fetch('port')
624
625
  }
625
626
  end
626
627
  end
@@ -39,6 +39,7 @@ class Redis
39
39
  def call_master(command, &block)
40
40
  try_map do |node_key, client|
41
41
  next if slave?(node_key)
42
+
42
43
  client.call(command, &block)
43
44
  end.values
44
45
  end
@@ -48,6 +49,7 @@ class Redis
48
49
 
49
50
  try_map do |node_key, client|
50
51
  next if master?(node_key)
52
+
51
53
  client.call(command, &block)
52
54
  end.values
53
55
  end
@@ -97,6 +99,7 @@ class Redis
97
99
  end
98
100
 
99
101
  return results if errors.empty?
102
+
100
103
  raise CommandErrorCollection, errors
101
104
  end
102
105
  end
@@ -43,6 +43,7 @@ class Redis
43
43
 
44
44
  def build_node_options(addrs)
45
45
  raise InvalidClientOptionError, 'Redis option of `cluster` must be an Array' unless addrs.is_a?(Array)
46
+
46
47
  addrs.map { |addr| parse_node_addr(addr) }
47
48
  end
48
49
 
@@ -69,7 +70,9 @@ class Redis
69
70
 
70
71
  def parse_node_option(addr)
71
72
  addr = addr.map { |k, v| [k.to_sym, v] }.to_h
72
- raise InvalidClientOptionError, 'Redis option of `cluster` must includes `:host` and `:port` keys' if addr.values_at(:host, :port).any?(&:nil?)
73
+ if addr.values_at(:host, :port).any?(&:nil?)
74
+ raise InvalidClientOptionError, 'Redis option of `cluster` must includes `:host` and `:port` keys'
75
+ end
73
76
 
74
77
  addr
75
78
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  class Redis
6
4
  class Cluster
7
5
  # Keep slot and node key map for Redis Cluster Client
@@ -28,11 +26,20 @@ class Redis
28
26
  return nil unless exists?(slot)
29
27
  return find_node_key_of_master(slot) if replica_disabled?
30
28
 
31
- @map[slot][:slaves].to_a.sample
29
+ @map[slot][:slaves].sample
32
30
  end
33
31
 
34
32
  def put(slot, node_key)
35
- assign_node_key(@map, slot, node_key)
33
+ # Since we're sharing a hash for build_slot_node_key_map, duplicate it
34
+ # if it already exists instead of preserving as-is.
35
+ @map[slot] = @map[slot] ? @map[slot].dup : { master: nil, slaves: [] }
36
+
37
+ if master?(node_key)
38
+ @map[slot][:master] = node_key
39
+ elsif !@map[slot][:slaves].include?(node_key)
40
+ @map[slot][:slaves] << node_key
41
+ end
42
+
36
43
  nil
37
44
  end
38
45
 
@@ -52,20 +59,27 @@ class Redis
52
59
 
53
60
  # available_slots is mapping of node_key to list of slot ranges
54
61
  def build_slot_node_key_map(available_slots)
55
- available_slots.each_with_object({}) do |(node_key, slots_arr), acc|
56
- slots_arr.each do |slots|
57
- slots.each { |slot| assign_node_key(acc, slot, node_key) }
62
+ by_ranges = {}
63
+ available_slots.each do |node_key, slots_arr|
64
+ by_ranges[slots_arr] ||= { master: nil, slaves: [] }
65
+
66
+ if master?(node_key)
67
+ by_ranges[slots_arr][:master] = node_key
68
+ elsif !by_ranges[slots_arr][:slaves].include?(node_key)
69
+ by_ranges[slots_arr][:slaves] << node_key
58
70
  end
59
71
  end
60
- end
61
72
 
62
- def assign_node_key(mappings, slot, node_key)
63
- mappings[slot] ||= { master: nil, slaves: ::Set.new }
64
- if master?(node_key)
65
- mappings[slot][:master] = node_key
66
- else
67
- mappings[slot][:slaves].add(node_key)
73
+ by_slot = {}
74
+ by_ranges.each do |slots_arr, nodes|
75
+ slots_arr.each do |slots|
76
+ slots.each do |slot|
77
+ by_slot[slot] = nodes
78
+ end
79
+ end
68
80
  end
81
+
82
+ by_slot
69
83
  end
70
84
  end
71
85
  end
@@ -25,9 +25,8 @@ class Redis
25
25
  def fetch_slot_info(node)
26
26
  hash_with_default_arr = Hash.new { |h, k| h[k] = [] }
27
27
  node.call(%i[cluster slots])
28
- .flat_map { |arr| parse_slot_info(arr, default_ip: node.host) }
29
- .each_with_object(hash_with_default_arr) { |arr, h| h[arr[0]] << arr[1] }
30
-
28
+ .flat_map { |arr| parse_slot_info(arr, default_ip: node.host) }
29
+ .each_with_object(hash_with_default_arr) { |arr, h| h[arr[0]] << arr[1] }
31
30
  rescue CannotConnectError, ConnectionError, CommandError
32
31
  {} # can retry on another node
33
32
  end
data/lib/redis/cluster.rb CHANGED
@@ -80,6 +80,7 @@ class Redis
80
80
  def call_pipeline(pipeline)
81
81
  node_keys, command_keys = extract_keys_in_pipeline(pipeline)
82
82
  raise CrossSlotPipeliningError, command_keys if node_keys.size > 1
83
+
83
84
  node = find_node(node_keys.first)
84
85
  try_send(node, :call_pipeline, pipeline)
85
86
  end
@@ -216,11 +217,13 @@ class Redis
216
217
  rescue CommandError => err
217
218
  if err.message.start_with?('MOVED')
218
219
  raise if retry_count <= 0
220
+
219
221
  node = assign_redirection_node(err.message)
220
222
  retry_count -= 1
221
223
  retry
222
224
  elsif err.message.start_with?('ASK')
223
225
  raise if retry_count <= 0
226
+
224
227
  node = assign_asking_node(err.message)
225
228
  node.call(%i[asking])
226
229
  retry_count -= 1
@@ -266,6 +269,7 @@ class Redis
266
269
 
267
270
  def find_node(node_key)
268
271
  return @node.sample if node_key.nil?
272
+
269
273
  @node.find_by(node_key)
270
274
  rescue Node::ReloadNeeded
271
275
  update_cluster_info!(node_key)
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Redis
3
4
  module Connection
4
5
  module CommandHelper
5
-
6
6
  COMMAND_DELIMITER = "\r\n"
7
7
 
8
8
  def build_command(args)
@@ -29,7 +29,7 @@ class Redis
29
29
  command.join(COMMAND_DELIMITER)
30
30
  end
31
31
 
32
- protected
32
+ protected
33
33
 
34
34
  def encode(string)
35
35
  string.force_encoding(Encoding.default_external)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "registry"
3
4
  require_relative "../errors"
4
5
  require "hiredis/connection"
@@ -7,7 +8,6 @@ require "timeout"
7
8
  class Redis
8
9
  module Connection
9
10
  class Hiredis
10
-
11
11
  def self.connect(config)
12
12
  connection = ::Hiredis::Connection.new
13
13
  connect_timeout = (config.fetch(:connect_timeout, 0) * 1_000_000).to_i
@@ -32,7 +32,7 @@ class Redis
32
32
  end
33
33
 
34
34
  def connected?
35
- @connection && @connection.connected?
35
+ @connection&.connected?
36
36
  end
37
37
 
38
38
  def timeout=(timeout)
@@ -58,7 +58,7 @@ class Redis
58
58
  rescue Errno::EAGAIN
59
59
  raise TimeoutError
60
60
  rescue RuntimeError => err
61
- raise ProtocolError.new(err.message)
61
+ raise ProtocolError, err.message
62
62
  end
63
63
  end
64
64
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Redis
3
4
  module Connection
4
-
5
5
  # Store a list of loaded connection drivers in the Connection module.
6
6
  # Redis::Client uses the last required driver by default, and will be aware
7
7
  # of the loaded connection drivers if the user chooses to override the