redis 4.1.4 → 4.2.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: 83f1f7270db68603d63e86ec43e68348cb5ccb2b4e6759642d89898566bdbaf6
4
- data.tar.gz: 45c5bcc92629ec7d85cdc2b913e7922cd5425f2e6691891efc379aeec73026b3
3
+ metadata.gz: 1e49d4c950b40f5d702b9b49bfc16b6af12dba334f5866dfd44f1ff69af55ecc
4
+ data.tar.gz: bf025908a9697cb0308aa3cbce20ecd292a5d9d801c53ad89f739ca5e5beb74f
5
5
  SHA512:
6
- metadata.gz: 692dfc5c73c6410492589f38f279976a023f6a2ff13f7b1476806011eb387f41bed784bdeac746de5f4b990b6d22bf297b36dddc7b8e448a842241a389f50796
7
- data.tar.gz: 55a9e305c7563f5dd7d38f50dc7b919967dbb0f6a131ebc5e1569f49f196ab458203b6594394fa9a33ea9e337b741113e781378113783683dd36b87196607b8f
6
+ metadata.gz: b27b0178a9120d2843017f5b153dfd48f668ad6b56058bc1058cc318034f1715491cbc9557d71459588b4d3c17970f2572efffd1e79523069ebc4bc208b1c193
7
+ data.tar.gz: e6ec5a2f2d49bebdef37531d0292f1076bde4ec81adc190eae122d972bb8b9d46354c78c1fc2d1340d392d5805b42a63409bf6fe4cd020c1176a31ed249bc450
@@ -1,5 +1,23 @@
1
1
  # Unreleased
2
2
 
3
+ # 4.2.1
4
+
5
+ * Fix `exists?` returning an actual boolean when called with multiple keys. See #918.
6
+ * Setting `Redis.exists_returns_integer = false` disables warning message about new behaviour. See #920.
7
+
8
+ # 4.2.0
9
+
10
+ * Convert commands to accept keyword arguments rather than option hashes. This both help catching typos, and reduce needless allocations.
11
+ * Deprecate the synchrony driver. It will be removed in 5.0 and hopefully maintained as a separate gem. See #915.
12
+ * Make `Redis#exists` variadic, will return an Integer if called with multiple keys.
13
+ * Add `Redis#exists?` to get a Boolean if any of the keys exists.
14
+ * `Redis#exists` when called with a single key will warn that future versions will return an Integer.
15
+ Set `Redis.exists_returns_integer = true` to opt-in to the new behavior.
16
+ * Support `keepttl` ooption in `set`. See #913.
17
+ * Optimized initialization of Redis::Cluster. See #912.
18
+ * Accept sentinel options even with string key. See #599.
19
+ * Verify TLS connections by default. See #900.
20
+
3
21
  # 4.1.4
4
22
 
5
23
  * Alias `Redis#disconnect` as `#close`. See #901.
@@ -9,6 +27,7 @@
9
27
  * Increase buffer size in the ruby connector. See #880.
10
28
  * Fix thread safety of `Redis.queue`. See #878.
11
29
  * Deprecate `Redis::Future#==` as it's likely to be a mistake. See #876.
30
+ * Support `KEEPTTL` option for SET command. See #913.
12
31
 
13
32
  # 4.1.3
14
33
 
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"
@@ -322,7 +326,7 @@ This library supports natively terminating client side SSL/TLS connections
322
326
  when talking to Redis via a server-side proxy such as [stunnel], [hitch],
323
327
  or [ghostunnel].
324
328
 
325
- To enable SSL support, pass the `:ssl => :true` option when configuring the
329
+ To enable SSL support, pass the `:ssl => true` option when configuring the
326
330
  Redis client, or pass in `:url => "rediss://..."` (like HTTPS for Redis).
327
331
  You will also need to pass in an `:ssl_params => { ... }` hash used to
328
332
  configure the `OpenSSL::SSL::SSLContext` object used for the connection:
@@ -451,7 +455,7 @@ client and evangelized Redis in Rubyland. Thank you, Ezra.
451
455
  ## Contributing
452
456
 
453
457
  [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.
458
+ requests.
455
459
 
456
460
 
457
461
  [inchpages-image]: https://inch-ci.org/github/redis/redis-rb.svg
@@ -4,12 +4,26 @@ require "monitor"
4
4
  require_relative "redis/errors"
5
5
 
6
6
  class Redis
7
- def self.current
8
- @current ||= Redis.new
7
+ class << self
8
+ attr_reader :exists_returns_integer
9
+
10
+ def exists_returns_integer=(value)
11
+ unless value
12
+ message = "`Redis#exists(key)` will return an Integer by default in redis-rb 4.3. The option to explicitly " \
13
+ "disable this behaviour via `Redis.exists_returns_integer` will be removed in 5.0. You should use " \
14
+ "`exists?` instead."
15
+
16
+ ::Kernel.warn(message)
17
+ end
18
+
19
+ @exists_returns_integer = value
20
+ end
21
+
22
+ attr_writer :current
9
23
  end
10
24
 
11
- def self.current=(redis)
12
- @current = redis
25
+ def self.current
26
+ @current ||= Redis.new
13
27
  end
14
28
 
15
29
  include MonitorMixin
@@ -17,7 +31,9 @@ class Redis
17
31
  # Create a new client instance
18
32
  #
19
33
  # @param [Hash] options
20
- # @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection: `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket connection: `unix://[path to Redis socket]`. This overrides all other options.
34
+ # @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection:
35
+ # `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket
36
+ # connection: `unix://[path to Redis socket]`. This overrides all other options.
21
37
  # @option options [String] :host ("127.0.0.1") server hostname
22
38
  # @option options [Integer] :port (6379) server port
23
39
  # @option options [String] :path path to server socket (overrides host and port)
@@ -26,8 +42,10 @@ class Redis
26
42
  # @option options [String] :password Password to authenticate against server
27
43
  # @option options [Integer] :db (0) Database to select after initial connect
28
44
  # @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`, `:synchrony`
29
- # @option options [String] :id ID for the client connection, assigns name to current connection by sending `CLIENT SETNAME`
30
- # @option options [Hash, Integer] :tcp_keepalive Keepalive values, if Integer `intvl` and `probe` are calculated based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer
45
+ # @option options [String] :id ID for the client connection, assigns name to current connection by sending
46
+ # `CLIENT SETNAME`
47
+ # @option options [Hash, Integer] :tcp_keepalive Keepalive values, if Integer `intvl` and `probe` are calculated
48
+ # based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer
31
49
  # @option options [Integer] :reconnect_attempts Number of attempts trying to connect
32
50
  # @option options [Boolean] :inherit_socket (false) Whether to use socket in forked process or not
33
51
  # @option options [Array] :sentinels List of sentinels to contact
@@ -52,7 +70,7 @@ class Redis
52
70
  end
53
71
 
54
72
  # Run code with the client reconnecting
55
- def with_reconnect(val=true, &blk)
73
+ def with_reconnect(val = true, &blk)
56
74
  synchronize do |client|
57
75
  client.with_reconnect(val, &blk)
58
76
  end
@@ -205,7 +223,7 @@ class Redis
205
223
  def config(action, *args)
206
224
  synchronize do |client|
207
225
  client.call([:config, action] + args) do |reply|
208
- if reply.kind_of?(Array) && action == :get
226
+ if reply.is_a?(Array) && action == :get
209
227
  Hashify.call(reply)
210
228
  else
211
229
  reply
@@ -256,7 +274,7 @@ class Redis
256
274
  def flushall(options = nil)
257
275
  synchronize do |client|
258
276
  if options && options[:async]
259
- client.call([:flushall, :async])
277
+ client.call(%i[flushall async])
260
278
  else
261
279
  client.call([:flushall])
262
280
  end
@@ -271,7 +289,7 @@ class Redis
271
289
  def flushdb(options = nil)
272
290
  synchronize do |client|
273
291
  if options && options[:async]
274
- client.call([:flushdb, :async])
292
+ client.call(%i[flushdb async])
275
293
  else
276
294
  client.call([:flushdb])
277
295
  end
@@ -285,7 +303,7 @@ class Redis
285
303
  def info(cmd = nil)
286
304
  synchronize do |client|
287
305
  client.call([:info, cmd].compact) do |reply|
288
- if reply.kind_of?(String)
306
+ if reply.is_a?(String)
289
307
  reply = HashifyInfo.call(reply)
290
308
 
291
309
  if cmd && cmd.to_s == "commandstats"
@@ -358,7 +376,7 @@ class Redis
358
376
  # @param [String] subcommand e.g. `get`, `len`, `reset`
359
377
  # @param [Integer] length maximum number of entries to return
360
378
  # @return [Array<String>, Integer, String] depends on subcommand
361
- def slowlog(subcommand, length=nil)
379
+ def slowlog(subcommand, length = nil)
362
380
  synchronize do |client|
363
381
  args = [:slowlog, subcommand]
364
382
  args << length if length
@@ -383,7 +401,7 @@ class Redis
383
401
  def time
384
402
  synchronize do |client|
385
403
  client.call([:time]) do |reply|
386
- reply.map(&:to_i) if reply
404
+ reply&.map(&:to_i)
387
405
  end
388
406
  end
389
407
  end
@@ -496,9 +514,9 @@ class Redis
496
514
  # - `:replace => Boolean`: if false, raises an error if key already exists
497
515
  # @raise [Redis::CommandError]
498
516
  # @return [String] `"OK"`
499
- def restore(key, ttl, serialized_value, options = {})
517
+ def restore(key, ttl, serialized_value, replace: nil)
500
518
  args = [:restore, key, ttl, serialized_value]
501
- args << 'REPLACE' if options[:replace]
519
+ args << 'REPLACE' if replace
502
520
 
503
521
  synchronize do |client|
504
522
  client.call(args)
@@ -550,13 +568,43 @@ class Redis
550
568
  end
551
569
  end
552
570
 
553
- # Determine if a key exists.
571
+ # Determine how many of the keys exists.
554
572
  #
555
- # @param [String] key
573
+ # @param [String, Array<String>] keys
574
+ # @return [Integer]
575
+ def exists(*keys)
576
+ if !Redis.exists_returns_integer && keys.size == 1
577
+ if Redis.exists_returns_integer.nil?
578
+ message = "`Redis#exists(key)` will return an Integer in redis-rb 4.3. `exists?` returns a boolean, you " \
579
+ "should use it instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer = " \
580
+ "true. To disable this message and keep the current (boolean) behaviour of 'exists' you can set " \
581
+ "`Redis.exists_returns_integer = false`, but this option will be removed in 5.0. " \
582
+ "(#{::Kernel.caller(1, 1).first})\n"
583
+
584
+ ::Kernel.warn(message)
585
+ end
586
+
587
+ exists?(*keys)
588
+ else
589
+ _exists(*keys)
590
+ end
591
+ end
592
+
593
+ def _exists(*keys)
594
+ synchronize do |client|
595
+ client.call([:exists, *keys])
596
+ end
597
+ end
598
+
599
+ # Determine if any of the keys exists.
600
+ #
601
+ # @param [String, Array<String>] keys
556
602
  # @return [Boolean]
557
- def exists(key)
603
+ def exists?(*keys)
558
604
  synchronize do |client|
559
- client.call([:exists, key], &Boolify)
605
+ client.call([:exists, *keys]) do |value|
606
+ value > 0
607
+ end
560
608
  end
561
609
  end
562
610
 
@@ -567,7 +615,7 @@ class Redis
567
615
  def keys(pattern = "*")
568
616
  synchronize do |client|
569
617
  client.call([:keys, pattern]) do |reply|
570
- if reply.kind_of?(String)
618
+ if reply.is_a?(String)
571
619
  reply.split(" ")
572
620
  else
573
621
  reply
@@ -663,30 +711,27 @@ class Redis
663
711
  # elements where every element is an array with the result for every
664
712
  # element specified in `:get`
665
713
  # - when `:store` is specified, the number of elements in the stored result
666
- def sort(key, options = {})
667
- args = []
714
+ def sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil)
715
+ args = [:sort, key]
716
+ args << "BY" << by if by
668
717
 
669
- by = options[:by]
670
- args.concat(["BY", by]) if by
671
-
672
- limit = options[:limit]
673
- args.concat(["LIMIT"] + limit) if limit
718
+ if limit
719
+ args << "LIMIT"
720
+ args.concat(limit)
721
+ end
674
722
 
675
- get = Array(options[:get])
676
- args.concat(["GET"].product(get).flatten) unless get.empty?
723
+ get = Array(get)
724
+ get.each do |item|
725
+ args << "GET" << item
726
+ end
677
727
 
678
- order = options[:order]
679
728
  args.concat(order.split(" ")) if order
680
-
681
- store = options[:store]
682
- args.concat(["STORE", store]) if store
729
+ args << "STORE" << store if store
683
730
 
684
731
  synchronize do |client|
685
- client.call([:sort, key] + args) do |reply|
732
+ client.call(args) do |reply|
686
733
  if get.size > 1 && !store
687
- if reply
688
- reply.each_slice(get.size).to_a
689
- end
734
+ reply.each_slice(get.size).to_a if reply
690
735
  else
691
736
  reply
692
737
  end
@@ -786,27 +831,21 @@ class Redis
786
831
  # - `:px => Integer`: Set the specified expire time, in milliseconds.
787
832
  # - `:nx => true`: Only set the key if it does not already exist.
788
833
  # - `:xx => true`: Only set the key if it already exist.
834
+ # - `:keepttl => true`: Retain the time to live associated with the key.
789
835
  # @return [String, Boolean] `"OK"` or true, false if `:nx => true` or `:xx => true`
790
- def set(key, value, options = {})
791
- args = []
792
-
793
- ex = options[:ex]
794
- args.concat(["EX", ex]) if ex
795
-
796
- px = options[:px]
797
- args.concat(["PX", px]) if px
798
-
799
- nx = options[:nx]
800
- args.concat(["NX"]) if nx
801
-
802
- xx = options[:xx]
803
- args.concat(["XX"]) if xx
836
+ def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil)
837
+ args = [:set, key, value.to_s]
838
+ args << "EX" << ex if ex
839
+ args << "PX" << px if px
840
+ args << "NX" if nx
841
+ args << "XX" if xx
842
+ args << "KEEPTTL" if keepttl
804
843
 
805
844
  synchronize do |client|
806
845
  if nx || xx
807
- client.call([:set, key, value.to_s] + args, &BoolifySet)
846
+ client.call(args, &BoolifySet)
808
847
  else
809
- client.call([:set, key, value.to_s] + args)
848
+ client.call(args)
810
849
  end
811
850
  end
812
851
  end
@@ -888,7 +927,7 @@ class Redis
888
927
  # @see #mapped_msetnx
889
928
  def msetnx(*args)
890
929
  synchronize do |client|
891
- client.call([:msetnx] + args, &Boolify)
930
+ client.call([:msetnx, *args], &Boolify)
892
931
  end
893
932
  end
894
933
 
@@ -928,7 +967,7 @@ class Redis
928
967
  # @see #mapped_mget
929
968
  def mget(*keys, &blk)
930
969
  synchronize do |client|
931
- client.call([:mget] + keys, &blk)
970
+ client.call([:mget, *keys], &blk)
932
971
  end
933
972
  end
934
973
 
@@ -944,7 +983,7 @@ class Redis
944
983
  # @see #mget
945
984
  def mapped_mget(*keys)
946
985
  mget(*keys) do |reply|
947
- if reply.kind_of?(Array)
986
+ if reply.is_a?(Array)
948
987
  Hash[keys.zip(reply)]
949
988
  else
950
989
  reply
@@ -1031,7 +1070,7 @@ class Redis
1031
1070
  # @return [Integer] the length of the string stored in `destkey`
1032
1071
  def bitop(operation, destkey, *keys)
1033
1072
  synchronize do |client|
1034
- client.call([:bitop, operation, destkey] + keys)
1073
+ client.call([:bitop, operation, destkey, *keys])
1035
1074
  end
1036
1075
  end
1037
1076
 
@@ -1043,10 +1082,8 @@ class Redis
1043
1082
  # @param [Integer] stop stop index
1044
1083
  # @return [Integer] the position of the first 1/0 bit.
1045
1084
  # -1 if looking for 1 and it is not found or start and stop are given.
1046
- def bitpos(key, bit, start=nil, stop=nil)
1047
- if stop and not start
1048
- raise(ArgumentError, 'stop parameter specified without start parameter')
1049
- end
1085
+ def bitpos(key, bit, start = nil, stop = nil)
1086
+ raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
1050
1087
 
1051
1088
  synchronize do |client|
1052
1089
  command = [:bitpos, key, bit]
@@ -1240,15 +1277,7 @@ class Redis
1240
1277
  # @return [nil, String]
1241
1278
  # - `nil` when the operation timed out
1242
1279
  # - the element was popped and pushed otherwise
1243
- def brpoplpush(source, destination, options = {})
1244
- case options
1245
- when Integer
1246
- # Issue deprecation notice in obnoxious mode...
1247
- options = { :timeout => options }
1248
- end
1249
-
1250
- timeout = options[:timeout] || 0
1251
-
1280
+ def brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout)
1252
1281
  synchronize do |client|
1253
1282
  command = [:brpoplpush, source, destination, timeout]
1254
1283
  timeout += client.timeout if timeout > 0
@@ -1455,7 +1484,7 @@ class Redis
1455
1484
  # @return [Array<String>] members in the difference
1456
1485
  def sdiff(*keys)
1457
1486
  synchronize do |client|
1458
- client.call([:sdiff] + keys)
1487
+ client.call([:sdiff, *keys])
1459
1488
  end
1460
1489
  end
1461
1490
 
@@ -1466,7 +1495,7 @@ class Redis
1466
1495
  # @return [Integer] number of elements in the resulting set
1467
1496
  def sdiffstore(destination, *keys)
1468
1497
  synchronize do |client|
1469
- client.call([:sdiffstore, destination] + keys)
1498
+ client.call([:sdiffstore, destination, *keys])
1470
1499
  end
1471
1500
  end
1472
1501
 
@@ -1476,7 +1505,7 @@ class Redis
1476
1505
  # @return [Array<String>] members in the intersection
1477
1506
  def sinter(*keys)
1478
1507
  synchronize do |client|
1479
- client.call([:sinter] + keys)
1508
+ client.call([:sinter, *keys])
1480
1509
  end
1481
1510
  end
1482
1511
 
@@ -1487,7 +1516,7 @@ class Redis
1487
1516
  # @return [Integer] number of elements in the resulting set
1488
1517
  def sinterstore(destination, *keys)
1489
1518
  synchronize do |client|
1490
- client.call([:sinterstore, destination] + keys)
1519
+ client.call([:sinterstore, destination, *keys])
1491
1520
  end
1492
1521
  end
1493
1522
 
@@ -1497,7 +1526,7 @@ class Redis
1497
1526
  # @return [Array<String>] members in the union
1498
1527
  def sunion(*keys)
1499
1528
  synchronize do |client|
1500
- client.call([:sunion] + keys)
1529
+ client.call([:sunion, *keys])
1501
1530
  end
1502
1531
  end
1503
1532
 
@@ -1508,7 +1537,7 @@ class Redis
1508
1537
  # @return [Integer] number of elements in the resulting set
1509
1538
  def sunionstore(destination, *keys)
1510
1539
  synchronize do |client|
1511
- client.call([:sunionstore, destination] + keys)
1540
+ client.call([:sunionstore, destination, *keys])
1512
1541
  end
1513
1542
  end
1514
1543
 
@@ -1557,31 +1586,20 @@ class Redis
1557
1586
  # pairs that were **added** to the sorted set.
1558
1587
  # - `Float` when option :incr is specified, holding the score of the member
1559
1588
  # after incrementing it.
1560
- def zadd(key, *args) #, options
1561
- zadd_options = []
1562
- if args.last.is_a?(Hash)
1563
- options = args.pop
1564
-
1565
- nx = options[:nx]
1566
- zadd_options << "NX" if nx
1567
-
1568
- xx = options[:xx]
1569
- zadd_options << "XX" if xx
1570
-
1571
- ch = options[:ch]
1572
- zadd_options << "CH" if ch
1573
-
1574
- incr = options[:incr]
1575
- zadd_options << "INCR" if incr
1576
- end
1589
+ def zadd(key, *args, nx: nil, xx: nil, ch: nil, incr: nil)
1590
+ command = [:zadd, key]
1591
+ command << "NX" if nx
1592
+ command << "XX" if xx
1593
+ command << "CH" if ch
1594
+ command << "INCR" if incr
1577
1595
 
1578
1596
  synchronize do |client|
1579
1597
  if args.size == 1 && args[0].is_a?(Array)
1580
1598
  # Variadic: return float if INCR, integer if !INCR
1581
- client.call([:zadd, key] + zadd_options + args[0], &(incr ? Floatify : nil))
1599
+ client.call(command + args[0], &(incr ? Floatify : nil))
1582
1600
  elsif args.size == 2
1583
1601
  # Single pair: return float if INCR, boolean if !INCR
1584
- client.call([:zadd, key] + zadd_options + args, &(incr ? Floatify : Boolify))
1602
+ client.call(command + args, &(incr ? Floatify : Boolify))
1585
1603
  else
1586
1604
  raise ArgumentError, "wrong number of arguments"
1587
1605
  end
@@ -1752,10 +1770,8 @@ class Redis
1752
1770
  # @return [Array<String>, Array<[String, Float]>]
1753
1771
  # - when `:with_scores` is not specified, an array of members
1754
1772
  # - when `:with_scores` is specified, an array with `[member, score]` pairs
1755
- def zrange(key, start, stop, options = {})
1756
- args = []
1757
-
1758
- with_scores = options[:with_scores] || options[:withscores]
1773
+ def zrange(key, start, stop, withscores: false, with_scores: withscores)
1774
+ args = [:zrange, key, start, stop]
1759
1775
 
1760
1776
  if with_scores
1761
1777
  args << "WITHSCORES"
@@ -1763,7 +1779,7 @@ class Redis
1763
1779
  end
1764
1780
 
1765
1781
  synchronize do |client|
1766
- client.call([:zrange, key, start, stop] + args, &block)
1782
+ client.call(args, &block)
1767
1783
  end
1768
1784
  end
1769
1785
 
@@ -1778,10 +1794,8 @@ class Redis
1778
1794
  # # => [["b", 64.0], ["a", 32.0]]
1779
1795
  #
1780
1796
  # @see #zrange
1781
- def zrevrange(key, start, stop, options = {})
1782
- args = []
1783
-
1784
- with_scores = options[:with_scores] || options[:withscores]
1797
+ def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
1798
+ args = [:zrevrange, key, start, stop]
1785
1799
 
1786
1800
  if with_scores
1787
1801
  args << "WITHSCORES"
@@ -1789,7 +1803,7 @@ class Redis
1789
1803
  end
1790
1804
 
1791
1805
  synchronize do |client|
1792
- client.call([:zrevrange, key, start, stop] + args, &block)
1806
+ client.call(args, &block)
1793
1807
  end
1794
1808
  end
1795
1809
 
@@ -1880,14 +1894,16 @@ class Redis
1880
1894
  # `count` members
1881
1895
  #
1882
1896
  # @return [Array<String>, Array<[String, Float]>]
1883
- def zrangebylex(key, min, max, options = {})
1884
- args = []
1897
+ def zrangebylex(key, min, max, limit: nil)
1898
+ args = [:zrangebylex, key, min, max]
1885
1899
 
1886
- limit = options[:limit]
1887
- args.concat(["LIMIT"] + limit) if limit
1900
+ if limit
1901
+ args << "LIMIT"
1902
+ args.concat(limit)
1903
+ end
1888
1904
 
1889
1905
  synchronize do |client|
1890
- client.call([:zrangebylex, key, min, max] + args)
1906
+ client.call(args)
1891
1907
  end
1892
1908
  end
1893
1909
 
@@ -1902,14 +1918,16 @@ class Redis
1902
1918
  # # => ["abbygail", "abby"]
1903
1919
  #
1904
1920
  # @see #zrangebylex
1905
- def zrevrangebylex(key, max, min, options = {})
1906
- args = []
1921
+ def zrevrangebylex(key, max, min, limit: nil)
1922
+ args = [:zrevrangebylex, key, max, min]
1907
1923
 
1908
- limit = options[:limit]
1909
- args.concat(["LIMIT"] + limit) if limit
1924
+ if limit
1925
+ args << "LIMIT"
1926
+ args.concat(limit)
1927
+ end
1910
1928
 
1911
1929
  synchronize do |client|
1912
- client.call([:zrevrangebylex, key, max, min] + args)
1930
+ client.call(args)
1913
1931
  end
1914
1932
  end
1915
1933
 
@@ -1940,21 +1958,21 @@ class Redis
1940
1958
  # @return [Array<String>, Array<[String, Float]>]
1941
1959
  # - when `:with_scores` is not specified, an array of members
1942
1960
  # - when `:with_scores` is specified, an array with `[member, score]` pairs
1943
- def zrangebyscore(key, min, max, options = {})
1944
- args = []
1945
-
1946
- with_scores = options[:with_scores] || options[:withscores]
1961
+ def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)
1962
+ args = [:zrangebyscore, key, min, max]
1947
1963
 
1948
1964
  if with_scores
1949
1965
  args << "WITHSCORES"
1950
1966
  block = FloatifyPairs
1951
1967
  end
1952
1968
 
1953
- limit = options[:limit]
1954
- args.concat(["LIMIT"] + limit) if limit
1969
+ if limit
1970
+ args << "LIMIT"
1971
+ args.concat(limit)
1972
+ end
1955
1973
 
1956
1974
  synchronize do |client|
1957
- client.call([:zrangebyscore, key, min, max] + args, &block)
1975
+ client.call(args, &block)
1958
1976
  end
1959
1977
  end
1960
1978
 
@@ -1972,21 +1990,21 @@ class Redis
1972
1990
  # # => [["b", 64.0], ["a", 32.0]]
1973
1991
  #
1974
1992
  # @see #zrangebyscore
1975
- def zrevrangebyscore(key, max, min, options = {})
1976
- args = []
1977
-
1978
- with_scores = options[:with_scores] || options[:withscores]
1993
+ def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)
1994
+ args = [:zrevrangebyscore, key, max, min]
1979
1995
 
1980
1996
  if with_scores
1981
- args << ["WITHSCORES"]
1997
+ args << "WITHSCORES"
1982
1998
  block = FloatifyPairs
1983
1999
  end
1984
2000
 
1985
- limit = options[:limit]
1986
- args.concat(["LIMIT"] + limit) if limit
2001
+ if limit
2002
+ args << "LIMIT"
2003
+ args.concat(limit)
2004
+ end
1987
2005
 
1988
2006
  synchronize do |client|
1989
- client.call([:zrevrangebyscore, key, max, min] + args, &block)
2007
+ client.call(args, &block)
1990
2008
  end
1991
2009
  end
1992
2010
 
@@ -2050,17 +2068,18 @@ class Redis
2050
2068
  # sorted sets
2051
2069
  # - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
2052
2070
  # @return [Integer] number of elements in the resulting sorted set
2053
- def zinterstore(destination, keys, options = {})
2054
- args = []
2071
+ def zinterstore(destination, keys, weights: nil, aggregate: nil)
2072
+ args = [:zinterstore, destination, keys.size, *keys]
2055
2073
 
2056
- weights = options[:weights]
2057
- args.concat(["WEIGHTS"] + weights) if weights
2074
+ if weights
2075
+ args << "WEIGHTS"
2076
+ args.concat(weights)
2077
+ end
2058
2078
 
2059
- aggregate = options[:aggregate]
2060
- args.concat(["AGGREGATE", aggregate]) if aggregate
2079
+ args << "AGGREGATE" << aggregate if aggregate
2061
2080
 
2062
2081
  synchronize do |client|
2063
- client.call([:zinterstore, destination, keys.size] + keys + args)
2082
+ client.call(args)
2064
2083
  end
2065
2084
  end
2066
2085
 
@@ -2077,17 +2096,18 @@ class Redis
2077
2096
  # sorted sets
2078
2097
  # - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
2079
2098
  # @return [Integer] number of elements in the resulting sorted set
2080
- def zunionstore(destination, keys, options = {})
2081
- args = []
2099
+ def zunionstore(destination, keys, weights: nil, aggregate: nil)
2100
+ args = [:zunionstore, destination, keys.size, *keys]
2082
2101
 
2083
- weights = options[:weights]
2084
- args.concat(["WEIGHTS"] + weights) if weights
2102
+ if weights
2103
+ args << "WEIGHTS"
2104
+ args.concat(weights)
2105
+ end
2085
2106
 
2086
- aggregate = options[:aggregate]
2087
- args.concat(["AGGREGATE", aggregate]) if aggregate
2107
+ args << "AGGREGATE" << aggregate if aggregate
2088
2108
 
2089
2109
  synchronize do |client|
2090
- client.call([:zunionstore, destination, keys.size] + keys + args)
2110
+ client.call(args)
2091
2111
  end
2092
2112
  end
2093
2113
 
@@ -2101,15 +2121,20 @@ class Redis
2101
2121
  end
2102
2122
  end
2103
2123
 
2104
- # Set the string value of a hash field.
2124
+ # Set one or more hash values.
2125
+ #
2126
+ # @example
2127
+ # redis.hset("hash", "f1", "v1", "f2", "v2") # => 2
2128
+ # redis.hset("hash", { "f1" => "v1", "f2" => "v2" }) # => 2
2105
2129
  #
2106
2130
  # @param [String] key
2107
- # @param [String] field
2108
- # @param [String] value
2109
- # @return [Boolean] whether or not the field was **added** to the hash
2110
- def hset(key, field, value)
2131
+ # @param [Array<String> | Hash<String, String>] attrs array or hash of fields and values
2132
+ # @return [Integer] The number of fields that were added to the hash
2133
+ def hset(key, *attrs)
2134
+ attrs = attrs.first.flatten if attrs.size == 1 && attrs.first.is_a?(Hash)
2135
+
2111
2136
  synchronize do |client|
2112
- client.call([:hset, key, field, value], &Boolify)
2137
+ client.call([:hset, key, *attrs])
2113
2138
  end
2114
2139
  end
2115
2140
 
@@ -2198,7 +2223,7 @@ class Redis
2198
2223
  # @see #hmget
2199
2224
  def mapped_hmget(key, *fields)
2200
2225
  hmget(key, *fields) do |reply|
2201
- if reply.kind_of?(Array)
2226
+ if reply.is_a?(Array)
2202
2227
  Hash[fields.zip(reply)]
2203
2228
  else
2204
2229
  reply
@@ -2291,20 +2316,21 @@ class Redis
2291
2316
 
2292
2317
  def subscribed?
2293
2318
  synchronize do |client|
2294
- client.kind_of? SubscribedClient
2319
+ client.is_a? SubscribedClient
2295
2320
  end
2296
2321
  end
2297
2322
 
2298
2323
  # Listen for messages published to the given channels.
2299
2324
  def subscribe(*channels, &block)
2300
- synchronize do |client|
2325
+ synchronize do |_client|
2301
2326
  _subscription(:subscribe, 0, channels, block)
2302
2327
  end
2303
2328
  end
2304
2329
 
2305
- # Listen for messages published to the given channels. Throw a timeout error if there is no messages for a timeout period.
2330
+ # Listen for messages published to the given channels. Throw a timeout error
2331
+ # if there is no messages for a timeout period.
2306
2332
  def subscribe_with_timeout(timeout, *channels, &block)
2307
- synchronize do |client|
2333
+ synchronize do |_client|
2308
2334
  _subscription(:subscribe_with_timeout, timeout, channels, block)
2309
2335
  end
2310
2336
  end
@@ -2312,21 +2338,23 @@ class Redis
2312
2338
  # Stop listening for messages posted to the given channels.
2313
2339
  def unsubscribe(*channels)
2314
2340
  synchronize do |client|
2315
- raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
2341
+ raise "Can't unsubscribe if not subscribed." unless subscribed?
2342
+
2316
2343
  client.unsubscribe(*channels)
2317
2344
  end
2318
2345
  end
2319
2346
 
2320
2347
  # Listen for messages published to channels matching the given patterns.
2321
2348
  def psubscribe(*channels, &block)
2322
- synchronize do |client|
2349
+ synchronize do |_client|
2323
2350
  _subscription(:psubscribe, 0, channels, block)
2324
2351
  end
2325
2352
  end
2326
2353
 
2327
- # Listen for messages published to channels matching the given patterns. Throw a timeout error if there is no messages for a timeout period.
2354
+ # Listen for messages published to channels matching the given patterns.
2355
+ # Throw a timeout error if there is no messages for a timeout period.
2328
2356
  def psubscribe_with_timeout(timeout, *channels, &block)
2329
- synchronize do |client|
2357
+ synchronize do |_client|
2330
2358
  _subscription(:psubscribe_with_timeout, timeout, channels, block)
2331
2359
  end
2332
2360
  end
@@ -2334,7 +2362,8 @@ class Redis
2334
2362
  # Stop listening for messages posted to channels matching the given patterns.
2335
2363
  def punsubscribe(*channels)
2336
2364
  synchronize do |client|
2337
- raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
2365
+ raise "Can't unsubscribe if not subscribed." unless subscribed?
2366
+
2338
2367
  client.punsubscribe(*channels)
2339
2368
  end
2340
2369
  end
@@ -2379,7 +2408,7 @@ class Redis
2379
2408
  # @see #multi
2380
2409
  def watch(*keys)
2381
2410
  synchronize do |client|
2382
- res = client.call([:watch] + keys)
2411
+ res = client.call([:watch, *keys])
2383
2412
 
2384
2413
  if block_given?
2385
2414
  begin
@@ -2409,7 +2438,7 @@ class Redis
2409
2438
  end
2410
2439
 
2411
2440
  def pipelined
2412
- synchronize do |client|
2441
+ synchronize do |_client|
2413
2442
  begin
2414
2443
  pipeline = Pipeline.new(@client)
2415
2444
  original, @client = @client, pipeline
@@ -2609,18 +2638,12 @@ class Redis
2609
2638
  _eval(:evalsha, args)
2610
2639
  end
2611
2640
 
2612
- def _scan(command, cursor, args, options = {}, &block)
2641
+ def _scan(command, cursor, args, match: nil, count: nil, &block)
2613
2642
  # SSCAN/ZSCAN/HSCAN already prepend the key to +args+.
2614
2643
 
2615
2644
  args << cursor
2616
-
2617
- if match = options[:match]
2618
- args.concat(["MATCH", match])
2619
- end
2620
-
2621
- if count = options[:count]
2622
- args.concat(["COUNT", count])
2623
- end
2645
+ args << "MATCH" << match if match
2646
+ args << "COUNT" << count if count
2624
2647
 
2625
2648
  synchronize do |client|
2626
2649
  client.call([command] + args, &block)
@@ -2642,8 +2665,8 @@ class Redis
2642
2665
  # - `:count => Integer`: return count keys at most per iteration
2643
2666
  #
2644
2667
  # @return [String, Array<String>] the next cursor and all found keys
2645
- def scan(cursor, options={})
2646
- _scan(:scan, cursor, [], options)
2668
+ def scan(cursor, **options)
2669
+ _scan(:scan, cursor, [], **options)
2647
2670
  end
2648
2671
 
2649
2672
  # Scan the keyspace
@@ -2661,11 +2684,12 @@ class Redis
2661
2684
  # - `:count => Integer`: return count keys at most per iteration
2662
2685
  #
2663
2686
  # @return [Enumerator] an enumerator for all found keys
2664
- def scan_each(options={}, &block)
2665
- return to_enum(:scan_each, options) unless block_given?
2687
+ def scan_each(**options, &block)
2688
+ return to_enum(:scan_each, **options) unless block_given?
2689
+
2666
2690
  cursor = 0
2667
2691
  loop do
2668
- cursor, keys = scan(cursor, options)
2692
+ cursor, keys = scan(cursor, **options)
2669
2693
  keys.each(&block)
2670
2694
  break if cursor == "0"
2671
2695
  end
@@ -2682,8 +2706,8 @@ class Redis
2682
2706
  # - `:count => Integer`: return count keys at most per iteration
2683
2707
  #
2684
2708
  # @return [String, Array<[String, String]>] the next cursor and all found keys
2685
- def hscan(key, cursor, options={})
2686
- _scan(:hscan, cursor, [key], options) do |reply|
2709
+ def hscan(key, cursor, **options)
2710
+ _scan(:hscan, cursor, [key], **options) do |reply|
2687
2711
  [reply[0], reply[1].each_slice(2).to_a]
2688
2712
  end
2689
2713
  end
@@ -2699,11 +2723,12 @@ class Redis
2699
2723
  # - `:count => Integer`: return count keys at most per iteration
2700
2724
  #
2701
2725
  # @return [Enumerator] an enumerator for all found keys
2702
- def hscan_each(key, options={}, &block)
2703
- return to_enum(:hscan_each, key, options) unless block_given?
2726
+ def hscan_each(key, **options, &block)
2727
+ return to_enum(:hscan_each, key, **options) unless block_given?
2728
+
2704
2729
  cursor = 0
2705
2730
  loop do
2706
- cursor, values = hscan(key, cursor, options)
2731
+ cursor, values = hscan(key, cursor, **options)
2707
2732
  values.each(&block)
2708
2733
  break if cursor == "0"
2709
2734
  end
@@ -2721,8 +2746,8 @@ class Redis
2721
2746
  #
2722
2747
  # @return [String, Array<[String, Float]>] the next cursor and all found
2723
2748
  # members and scores
2724
- def zscan(key, cursor, options={})
2725
- _scan(:zscan, cursor, [key], options) do |reply|
2749
+ def zscan(key, cursor, **options)
2750
+ _scan(:zscan, cursor, [key], **options) do |reply|
2726
2751
  [reply[0], FloatifyPairs.call(reply[1])]
2727
2752
  end
2728
2753
  end
@@ -2738,11 +2763,12 @@ class Redis
2738
2763
  # - `:count => Integer`: return count keys at most per iteration
2739
2764
  #
2740
2765
  # @return [Enumerator] an enumerator for all found scores and members
2741
- def zscan_each(key, options={}, &block)
2742
- return to_enum(:zscan_each, key, options) unless block_given?
2766
+ def zscan_each(key, **options, &block)
2767
+ return to_enum(:zscan_each, key, **options) unless block_given?
2768
+
2743
2769
  cursor = 0
2744
2770
  loop do
2745
- cursor, values = zscan(key, cursor, options)
2771
+ cursor, values = zscan(key, cursor, **options)
2746
2772
  values.each(&block)
2747
2773
  break if cursor == "0"
2748
2774
  end
@@ -2759,8 +2785,8 @@ class Redis
2759
2785
  # - `:count => Integer`: return count keys at most per iteration
2760
2786
  #
2761
2787
  # @return [String, Array<String>] the next cursor and all found members
2762
- def sscan(key, cursor, options={})
2763
- _scan(:sscan, cursor, [key], options)
2788
+ def sscan(key, cursor, **options)
2789
+ _scan(:sscan, cursor, [key], **options)
2764
2790
  end
2765
2791
 
2766
2792
  # Scan a set
@@ -2774,11 +2800,12 @@ class Redis
2774
2800
  # - `:count => Integer`: return count keys at most per iteration
2775
2801
  #
2776
2802
  # @return [Enumerator] an enumerator for all keys in the set
2777
- def sscan_each(key, options={}, &block)
2778
- return to_enum(:sscan_each, key, options) unless block_given?
2803
+ def sscan_each(key, **options, &block)
2804
+ return to_enum(:sscan_each, key, **options) unless block_given?
2805
+
2779
2806
  cursor = 0
2780
2807
  loop do
2781
- cursor, keys = sscan(key, cursor, options)
2808
+ cursor, keys = sscan(key, cursor, **options)
2782
2809
  keys.each(&block)
2783
2810
  break if cursor == "0"
2784
2811
  end
@@ -2842,12 +2869,12 @@ class Redis
2842
2869
  end
2843
2870
  end
2844
2871
 
2845
-
2846
2872
  # Query a sorted set representing a geospatial index to fetch members matching a
2847
2873
  # given maximum distance from a point
2848
2874
  #
2849
2875
  # @param [Array] args key, longitude, latitude, radius, unit(m|km|ft|mi)
2850
- # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center
2876
+ # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest
2877
+ # or the farthest to the nearest relative to the center
2851
2878
  # @param [Integer] count limit the results to the first N matching items
2852
2879
  # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
2853
2880
  # @return [Array<String>] may be changed with `options`
@@ -2864,7 +2891,8 @@ class Redis
2864
2891
  # given maximum distance from an already existing member
2865
2892
  #
2866
2893
  # @param [Array] args key, member, radius, unit(m|km|ft|mi)
2867
- # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center
2894
+ # @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest
2895
+ # to the nearest relative to the center
2868
2896
  # @param [Integer] count limit the results to the first N matching items
2869
2897
  # @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
2870
2898
  # @return [Array<String>] may be changed with `options`
@@ -2881,7 +2909,8 @@ class Redis
2881
2909
  #
2882
2910
  # @param [String] key
2883
2911
  # @param [String, Array<String>] member one member or array of members
2884
- # @return [Array<Array<String>, nil>] returns array of elements, where each element is either array of longitude and latitude or nil
2912
+ # @return [Array<Array<String>, nil>] returns array of elements, where each
2913
+ # element is either array of longitude and latitude or nil
2885
2914
  def geopos(key, member)
2886
2915
  synchronize do |client|
2887
2916
  client.call([:geopos, key, member])
@@ -2945,10 +2974,14 @@ class Redis
2945
2974
  # @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
2946
2975
  #
2947
2976
  # @return [String] the entry id
2948
- def xadd(key, entry, opts = {})
2977
+ def xadd(key, entry, approximate: nil, maxlen: nil, id: '*')
2949
2978
  args = [:xadd, key]
2950
- args.concat(['MAXLEN', (opts[:approximate] ? '~' : nil), opts[:maxlen]].compact) if opts[:maxlen]
2951
- args << (opts[:id] || '*')
2979
+ if maxlen
2980
+ args << "MAXLEN"
2981
+ args << "~" if approximate
2982
+ args << maxlen
2983
+ end
2984
+ args << id
2952
2985
  args.concat(entry.to_a.flatten)
2953
2986
  synchronize { |client| client.call(args) }
2954
2987
  end
@@ -3003,8 +3036,8 @@ class Redis
3003
3036
  # @param count [Integer] the number of entries as limit
3004
3037
  #
3005
3038
  # @return [Array<Array<String, Hash>>] the ids and entries pairs
3006
- def xrange(key, start = '-', _end = '+', count: nil)
3007
- args = [:xrange, key, start, _end]
3039
+ def xrange(key, start = '-', range_end = '+', count: nil)
3040
+ args = [:xrange, key, start, range_end]
3008
3041
  args.concat(['COUNT', count]) if count
3009
3042
  synchronize { |client| client.call(args, &HashifyStreamEntries) }
3010
3043
  end
@@ -3026,8 +3059,8 @@ class Redis
3026
3059
  # @params count [Integer] the number of entries as limit
3027
3060
  #
3028
3061
  # @return [Array<Array<String, Hash>>] the ids and entries pairs
3029
- def xrevrange(key, _end = '+', start = '-', count: nil)
3030
- args = [:xrevrange, key, _end, start]
3062
+ def xrevrange(key, range_end = '+', start = '-', count: nil)
3063
+ args = [:xrevrange, key, range_end, start]
3031
3064
  args.concat(['COUNT', count]) if count
3032
3065
  synchronize { |client| client.call(args, &HashifyStreamEntries) }
3033
3066
  end
@@ -3119,12 +3152,12 @@ class Redis
3119
3152
  # @option opts [Boolean] :noack whether message loss is acceptable or not
3120
3153
  #
3121
3154
  # @return [Hash{String => Hash{String => Hash}}] the entries
3122
- def xreadgroup(group, consumer, keys, ids, opts = {})
3155
+ def xreadgroup(group, consumer, keys, ids, count: nil, block: nil, noack: nil)
3123
3156
  args = [:xreadgroup, 'GROUP', group, consumer]
3124
- args << 'COUNT' << opts[:count] if opts[:count]
3125
- args << 'BLOCK' << opts[:block].to_i if opts[:block]
3126
- args << 'NOACK' if opts[:noack]
3127
- _xread(args, keys, ids, opts[:block])
3157
+ args << 'COUNT' << count if count
3158
+ args << 'BLOCK' << block.to_i if block
3159
+ args << 'NOACK' if noack
3160
+ _xread(args, keys, ids, block)
3128
3161
  end
3129
3162
 
3130
3163
  # Removes one or multiple entries from the pending entries list of a stream consumer group.
@@ -3234,8 +3267,8 @@ class Redis
3234
3267
  when "get-master-addr-by-name"
3235
3268
  reply
3236
3269
  else
3237
- if reply.kind_of?(Array)
3238
- if reply[0].kind_of?(Array)
3270
+ if reply.is_a?(Array)
3271
+ if reply[0].is_a?(Array)
3239
3272
  reply.map(&Hashify)
3240
3273
  else
3241
3274
  Hashify.call(reply)
@@ -3259,12 +3292,17 @@ class Redis
3259
3292
  def cluster(subcommand, *args)
3260
3293
  subcommand = subcommand.to_s.downcase
3261
3294
  block = case subcommand
3262
- when 'slots' then HashifyClusterSlots
3263
- when 'nodes' then HashifyClusterNodes
3264
- when 'slaves' then HashifyClusterSlaves
3265
- when 'info' then HashifyInfo
3266
- else Noop
3267
- end
3295
+ when 'slots'
3296
+ HashifyClusterSlots
3297
+ when 'nodes'
3298
+ HashifyClusterNodes
3299
+ when 'slaves'
3300
+ HashifyClusterSlaves
3301
+ when 'info'
3302
+ HashifyInfo
3303
+ else
3304
+ Noop
3305
+ end
3268
3306
 
3269
3307
  # @see https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb#L127 raw reply expected
3270
3308
  block = Noop unless @cluster_mode
@@ -3299,21 +3337,21 @@ class Redis
3299
3337
  return @original_client.connection_info if @cluster_mode
3300
3338
 
3301
3339
  {
3302
- host: @original_client.host,
3303
- port: @original_client.port,
3304
- db: @original_client.db,
3305
- id: @original_client.id,
3340
+ host: @original_client.host,
3341
+ port: @original_client.port,
3342
+ db: @original_client.db,
3343
+ id: @original_client.id,
3306
3344
  location: @original_client.location
3307
3345
  }
3308
3346
  end
3309
3347
 
3310
- def method_missing(command, *args)
3348
+ def method_missing(command, *args) # rubocop:disable Style/MissingRespondToMissing
3311
3349
  synchronize do |client|
3312
3350
  client.call([command] + args)
3313
3351
  end
3314
3352
  end
3315
3353
 
3316
- private
3354
+ private
3317
3355
 
3318
3356
  # Commands returning 1 for true and 0 for false may be executed in a pipeline
3319
3357
  # where the method call will return nil. Propagate the nil instead of falsely
@@ -3393,10 +3431,10 @@ private
3393
3431
 
3394
3432
  HashifyStreamPendings = lambda { |reply|
3395
3433
  {
3396
- 'size' => reply[0],
3434
+ 'size' => reply[0],
3397
3435
  'min_entry_id' => reply[1],
3398
3436
  'max_entry_id' => reply[2],
3399
- 'consumers' => reply[3].nil? ? {} : reply[3].to_h
3437
+ 'consumers' => reply[3].nil? ? {} : reply[3].to_h
3400
3438
  }
3401
3439
  }
3402
3440
 
@@ -3405,8 +3443,8 @@ private
3405
3443
  {
3406
3444
  'entry_id' => arr[0],
3407
3445
  'consumer' => arr[1],
3408
- 'elapsed' => arr[2],
3409
- 'count' => arr[3]
3446
+ 'elapsed' => arr[2],
3447
+ 'count' => arr[3]
3410
3448
  }
3411
3449
  end
3412
3450
  }
@@ -3414,15 +3452,15 @@ private
3414
3452
  HashifyClusterNodeInfo = lambda { |str|
3415
3453
  arr = str.split(' ')
3416
3454
  {
3417
- 'node_id' => arr[0],
3418
- 'ip_port' => arr[1],
3419
- 'flags' => arr[2].split(','),
3455
+ 'node_id' => arr[0],
3456
+ 'ip_port' => arr[1],
3457
+ 'flags' => arr[2].split(','),
3420
3458
  'master_node_id' => arr[3],
3421
- 'ping_sent' => arr[4],
3422
- 'pong_recv' => arr[5],
3423
- 'config_epoch' => arr[6],
3424
- 'link_state' => arr[7],
3425
- 'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-'))
3459
+ 'ping_sent' => arr[4],
3460
+ 'pong_recv' => arr[5],
3461
+ 'config_epoch' => arr[6],
3462
+ 'link_state' => arr[7],
3463
+ 'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-'))
3426
3464
  }
3427
3465
  }
3428
3466
 
@@ -3433,9 +3471,9 @@ private
3433
3471
  replicas = arr[3..-1].map { |r| { 'ip' => r[0], 'port' => r[1], 'node_id' => r[2] } }
3434
3472
  {
3435
3473
  'start_slot' => first_slot,
3436
- 'end_slot' => last_slot,
3437
- 'master' => master,
3438
- 'replicas' => replicas
3474
+ 'end_slot' => last_slot,
3475
+ 'master' => master,
3476
+ 'replicas' => replicas
3439
3477
  }
3440
3478
  end
3441
3479
  }