redis 4.7.1 → 5.0.4

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/README.md +75 -161
  4. data/lib/redis/client.rb +92 -608
  5. data/lib/redis/commands/bitmaps.rb +4 -1
  6. data/lib/redis/commands/cluster.rb +1 -18
  7. data/lib/redis/commands/connection.rb +5 -10
  8. data/lib/redis/commands/geo.rb +3 -3
  9. data/lib/redis/commands/hashes.rb +8 -5
  10. data/lib/redis/commands/hyper_log_log.rb +1 -1
  11. data/lib/redis/commands/keys.rb +53 -27
  12. data/lib/redis/commands/lists.rb +19 -23
  13. data/lib/redis/commands/pubsub.rb +7 -25
  14. data/lib/redis/commands/server.rb +15 -15
  15. data/lib/redis/commands/sets.rb +43 -36
  16. data/lib/redis/commands/sorted_sets.rb +18 -12
  17. data/lib/redis/commands/streams.rb +12 -10
  18. data/lib/redis/commands/strings.rb +16 -15
  19. data/lib/redis/commands/transactions.rb +7 -31
  20. data/lib/redis/commands.rb +1 -8
  21. data/lib/redis/distributed.rb +100 -67
  22. data/lib/redis/errors.rb +14 -50
  23. data/lib/redis/hash_ring.rb +26 -26
  24. data/lib/redis/pipeline.rb +43 -222
  25. data/lib/redis/subscribe.rb +23 -15
  26. data/lib/redis/version.rb +1 -1
  27. data/lib/redis.rb +88 -182
  28. metadata +9 -53
  29. data/lib/redis/cluster/command.rb +0 -79
  30. data/lib/redis/cluster/command_loader.rb +0 -33
  31. data/lib/redis/cluster/key_slot_converter.rb +0 -72
  32. data/lib/redis/cluster/node.rb +0 -120
  33. data/lib/redis/cluster/node_key.rb +0 -31
  34. data/lib/redis/cluster/node_loader.rb +0 -34
  35. data/lib/redis/cluster/option.rb +0 -100
  36. data/lib/redis/cluster/slot.rb +0 -86
  37. data/lib/redis/cluster/slot_loader.rb +0 -46
  38. data/lib/redis/cluster.rb +0 -315
  39. data/lib/redis/connection/command_helper.rb +0 -41
  40. data/lib/redis/connection/hiredis.rb +0 -66
  41. data/lib/redis/connection/registry.rb +0 -13
  42. data/lib/redis/connection/ruby.rb +0 -437
  43. data/lib/redis/connection/synchrony.rb +0 -148
  44. data/lib/redis/connection.rb +0 -11
@@ -136,7 +136,9 @@ class Redis
136
136
  # @return [Array<String, Float>] element and score pair if count is not specified
137
137
  # @return [Array<Array<String, Float>>] list of popped elements and scores
138
138
  def zpopmax(key, count = nil)
139
- send_command([:zpopmax, key, count].compact) do |members|
139
+ command = [:zpopmax, key]
140
+ command << Integer(count) if count
141
+ send_command(command) do |members|
140
142
  members = FloatifyPairs.call(members)
141
143
  count.to_i > 1 ? members : members.first
142
144
  end
@@ -157,7 +159,9 @@ class Redis
157
159
  # @return [Array<String, Float>] element and score pair if count is not specified
158
160
  # @return [Array<Array<String, Float>>] list of popped elements and scores
159
161
  def zpopmin(key, count = nil)
160
- send_command([:zpopmin, key, count].compact) do |members|
162
+ command = [:zpopmin, key]
163
+ command << Integer(count) if count
164
+ send_command(command) do |members|
161
165
  members = FloatifyPairs.call(members)
162
166
  count.to_i > 1 ? members : members.first
163
167
  end
@@ -261,7 +265,7 @@ class Redis
261
265
  end
262
266
 
263
267
  args = [:zrandmember, key]
264
- args << count if count
268
+ args << Integer(count) if count
265
269
 
266
270
  if with_scores
267
271
  args << "WITHSCORES"
@@ -313,7 +317,7 @@ class Redis
313
317
 
314
318
  if limit
315
319
  args << "LIMIT"
316
- args.concat(limit)
320
+ args.concat(limit.map { |l| Integer(l) })
317
321
  end
318
322
 
319
323
  if with_scores
@@ -354,7 +358,7 @@ class Redis
354
358
 
355
359
  if limit
356
360
  args << "LIMIT"
357
- args.concat(limit)
361
+ args.concat(limit.map { |l| Integer(l) })
358
362
  end
359
363
 
360
364
  send_command(args)
@@ -372,7 +376,7 @@ class Redis
372
376
  #
373
377
  # @see #zrange
374
378
  def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
375
- args = [:zrevrange, key, start, stop]
379
+ args = [:zrevrange, key, Integer(start), Integer(stop)]
376
380
 
377
381
  if with_scores
378
382
  args << "WITHSCORES"
@@ -466,7 +470,7 @@ class Redis
466
470
 
467
471
  if limit
468
472
  args << "LIMIT"
469
- args.concat(limit)
473
+ args.concat(limit.map { |l| Integer(l) })
470
474
  end
471
475
 
472
476
  send_command(args)
@@ -488,7 +492,7 @@ class Redis
488
492
 
489
493
  if limit
490
494
  args << "LIMIT"
491
- args.concat(limit)
495
+ args.concat(limit.map { |l| Integer(l) })
492
496
  end
493
497
 
494
498
  send_command(args)
@@ -531,7 +535,7 @@ class Redis
531
535
 
532
536
  if limit
533
537
  args << "LIMIT"
534
- args.concat(limit)
538
+ args.concat(limit.map { |l| Integer(l) })
535
539
  end
536
540
 
537
541
  send_command(args, &block)
@@ -561,7 +565,7 @@ class Redis
561
565
 
562
566
  if limit
563
567
  args << "LIMIT"
564
- args.concat(limit)
568
+ args.concat(limit.map { |l| Integer(l) })
565
569
  end
566
570
 
567
571
  send_command(args, &block)
@@ -778,7 +782,8 @@ class Redis
778
782
  private
779
783
 
780
784
  def _zsets_operation(cmd, *keys, weights: nil, aggregate: nil, with_scores: false)
781
- command = [cmd, keys.size, *keys]
785
+ keys.flatten!(1)
786
+ command = [cmd, keys.size].concat(keys)
782
787
 
783
788
  if weights
784
789
  command << "WEIGHTS"
@@ -796,7 +801,8 @@ class Redis
796
801
  end
797
802
 
798
803
  def _zsets_operation_store(cmd, destination, keys, weights: nil, aggregate: nil)
799
- command = [cmd, destination, keys.size, *keys]
804
+ keys.flatten!(1)
805
+ command = [cmd, destination, keys.size].concat(keys)
800
806
 
801
807
  if weights
802
808
  command << "WEIGHTS"
@@ -21,15 +21,12 @@ class Redis
21
21
  # @return [Array<Hash>] information of the consumers if subcommand is `consumers`
22
22
  def xinfo(subcommand, key, group = nil)
23
23
  args = [:xinfo, subcommand, key, group].compact
24
- synchronize do |client|
25
- client.call(args) do |reply|
26
- case subcommand.to_s.downcase
27
- when 'stream' then Hashify.call(reply)
28
- when 'groups', 'consumers' then reply.map { |arr| Hashify.call(arr) }
29
- else reply
30
- end
31
- end
24
+ block = case subcommand.to_s.downcase
25
+ when 'stream' then Hashify
26
+ when 'groups', 'consumers' then proc { |r| r.map(&Hashify) }
32
27
  end
28
+
29
+ send_command(args, &block)
33
30
  end
34
31
 
35
32
  # Add new entry to the stream.
@@ -113,7 +110,7 @@ class Redis
113
110
  def xrange(key, start = '-', range_end = '+', count: nil)
114
111
  args = [:xrange, key, start, range_end]
115
112
  args.concat(['COUNT', count]) if count
116
- synchronize { |client| client.call(args, &HashifyStreamEntries) }
113
+ send_command(args, &HashifyStreamEntries)
117
114
  end
118
115
 
119
116
  # Fetches entries of the stream in descending order.
@@ -334,6 +331,8 @@ class Redis
334
331
  # redis.xpending('mystream', 'mygroup')
335
332
  # @example With range options
336
333
  # redis.xpending('mystream', 'mygroup', '-', '+', 10)
334
+ # @example With range and idle time options
335
+ # redis.xpending('mystream', 'mygroup', '-', '+', 10, idle: 9000)
337
336
  # @example With range and consumer options
338
337
  # redis.xpending('mystream', 'mygroup', '-', '+', 10, 'consumer1')
339
338
  #
@@ -344,10 +343,13 @@ class Redis
344
343
  # @param count [Integer] count the number of entries as limit
345
344
  # @param consumer [String] the consumer name
346
345
  #
346
+ # @option opts [Integer] :idle pending message minimum idle time in milliseconds
347
+ #
347
348
  # @return [Hash] the summary of pending entries
348
349
  # @return [Array<Hash>] the pending entries details if options were specified
349
- def xpending(key, group, *args)
350
+ def xpending(key, group, *args, idle: nil)
350
351
  command_args = [:xpending, key, group]
352
+ command_args << 'IDLE' << Integer(idle) if idle
351
353
  case args.size
352
354
  when 0, 3, 4
353
355
  command_args.concat(args)
@@ -25,7 +25,7 @@ class Redis
25
25
  # @param [Integer] decrement
26
26
  # @return [Integer] value after decrementing it
27
27
  def decrby(key, decrement)
28
- send_command([:decrby, key, decrement])
28
+ send_command([:decrby, key, Integer(decrement)])
29
29
  end
30
30
 
31
31
  # Increment the integer value of a key by one.
@@ -50,7 +50,7 @@ class Redis
50
50
  # @param [Integer] increment
51
51
  # @return [Integer] value after incrementing it
52
52
  def incrby(key, increment)
53
- send_command([:incrby, key, increment])
53
+ send_command([:incrby, key, Integer(increment)])
54
54
  end
55
55
 
56
56
  # Increment the numeric value of a key by the given float number.
@@ -63,7 +63,7 @@ class Redis
63
63
  # @param [Float] increment
64
64
  # @return [Float] value after incrementing it
65
65
  def incrbyfloat(key, increment)
66
- send_command([:incrbyfloat, key, increment], &Floatify)
66
+ send_command([:incrbyfloat, key, Float(increment)], &Floatify)
67
67
  end
68
68
 
69
69
  # Set the string value of a key.
@@ -82,10 +82,10 @@ class Redis
82
82
  # @return [String, Boolean] `"OK"` or true, false if `:nx => true` or `:xx => true`
83
83
  def set(key, value, ex: nil, px: nil, exat: nil, pxat: nil, nx: nil, xx: nil, keepttl: nil, get: nil)
84
84
  args = [:set, key, value.to_s]
85
- args << "EX" << ex if ex
86
- args << "PX" << px if px
87
- args << "EXAT" << exat if exat
88
- args << "PXAT" << pxat if pxat
85
+ args << "EX" << Integer(ex) if ex
86
+ args << "PX" << Integer(px) if px
87
+ args << "EXAT" << Integer(exat) if exat
88
+ args << "PXAT" << Integer(pxat) if pxat
89
89
  args << "NX" if nx
90
90
  args << "XX" if xx
91
91
  args << "KEEPTTL" if keepttl
@@ -105,7 +105,7 @@ class Redis
105
105
  # @param [String] value
106
106
  # @return [String] `"OK"`
107
107
  def setex(key, ttl, value)
108
- send_command([:setex, key, ttl, value.to_s])
108
+ send_command([:setex, key, Integer(ttl), value.to_s])
109
109
  end
110
110
 
111
111
  # Set the time to live in milliseconds of a key.
@@ -115,7 +115,7 @@ class Redis
115
115
  # @param [String] value
116
116
  # @return [String] `"OK"`
117
117
  def psetex(key, ttl, value)
118
- send_command([:psetex, key, ttl, value.to_s])
118
+ send_command([:psetex, key, Integer(ttl), value.to_s])
119
119
  end
120
120
 
121
121
  # Set the value of a key, only if the key does not exist.
@@ -202,6 +202,7 @@ class Redis
202
202
  #
203
203
  # @see #mapped_mget
204
204
  def mget(*keys, &blk)
205
+ keys.flatten!(1)
205
206
  send_command([:mget, *keys], &blk)
206
207
  end
207
208
 
@@ -232,7 +233,7 @@ class Redis
232
233
  # @param [String] value
233
234
  # @return [Integer] length of the string after it was modified
234
235
  def setrange(key, offset, value)
235
- send_command([:setrange, key, offset, value.to_s])
236
+ send_command([:setrange, key, Integer(offset), value.to_s])
236
237
  end
237
238
 
238
239
  # Get a substring of the string stored at a key.
@@ -243,7 +244,7 @@ class Redis
243
244
  # the end of the string
244
245
  # @return [Integer] `0` or `1`
245
246
  def getrange(key, start, stop)
246
- send_command([:getrange, key, start, stop])
247
+ send_command([:getrange, key, Integer(start), Integer(stop)])
247
248
  end
248
249
 
249
250
  # Append a value to a key.
@@ -291,10 +292,10 @@ class Redis
291
292
  # @return [String] The value of key, or nil when key does not exist.
292
293
  def getex(key, ex: nil, px: nil, exat: nil, pxat: nil, persist: false)
293
294
  args = [:getex, key]
294
- args << "EX" << ex if ex
295
- args << "PX" << px if px
296
- args << "EXAT" << exat if exat
297
- args << "PXAT" << pxat if pxat
295
+ args << "EX" << Integer(ex) if ex
296
+ args << "PX" << Integer(px) if px
297
+ args << "EXAT" << Integer(exat) if exat
298
+ args << "PXAT" << Integer(pxat) if pxat
298
299
  args << "PERSIST" if persist
299
300
 
300
301
  send_command(args)
@@ -5,48 +5,26 @@ class Redis
5
5
  module Transactions
6
6
  # Mark the start of a transaction block.
7
7
  #
8
- # Passing a block is optional.
9
- #
10
8
  # @example With a block
11
9
  # redis.multi do |multi|
12
10
  # multi.set("key", "value")
13
11
  # multi.incr("counter")
14
12
  # end # => ["OK", 6]
15
13
  #
16
- # @example Without a block
17
- # redis.multi
18
- # # => "OK"
19
- # redis.set("key", "value")
20
- # # => "QUEUED"
21
- # redis.incr("counter")
22
- # # => "QUEUED"
23
- # redis.exec
24
- # # => ["OK", 6]
25
- #
26
14
  # @yield [multi] the commands that are called inside this block are cached
27
15
  # and written to the server upon returning from it
28
16
  # @yieldparam [Redis] multi `self`
29
17
  #
30
- # @return [String, Array<...>]
31
- # - when a block is not given, `OK`
32
- # - when a block is given, an array with replies
18
+ # @return [Array<...>]
19
+ # - an array with replies
33
20
  #
34
21
  # @see #watch
35
22
  # @see #unwatch
36
- def multi(&block) # :nodoc:
37
- if block_given?
38
- if block&.arity == 0
39
- Pipeline.deprecation_warning("multi", Kernel.caller_locations(1, 5))
40
- end
41
-
42
- synchronize do |prior_client|
43
- pipeline = Pipeline::Multi.new(prior_client)
44
- pipelined_connection = PipelinedConnection.new(pipeline)
45
- yield pipelined_connection
46
- prior_client.call_pipeline(pipeline)
23
+ def multi
24
+ synchronize do |client|
25
+ client.multi do |raw_transaction|
26
+ yield MultiConnection.new(raw_transaction)
47
27
  end
48
- else
49
- send_command([:multi])
50
28
  end
51
29
  end
52
30
 
@@ -82,7 +60,7 @@ class Redis
82
60
  # @see #multi
83
61
  def watch(*keys)
84
62
  synchronize do |client|
85
- res = client.call([:watch, *keys])
63
+ res = client.call_v([:watch] + keys)
86
64
 
87
65
  if block_given?
88
66
  begin
@@ -125,8 +103,6 @@ class Redis
125
103
 
126
104
  # Discard all commands issued after MULTI.
127
105
  #
128
- # Only call this method when `#multi` was called **without** a block.
129
- #
130
106
  # @return [String] `"OK"`
131
107
  #
132
108
  # @see #multi
@@ -40,14 +40,7 @@ class Redis
40
40
  # where the method call will return nil. Propagate the nil instead of falsely
41
41
  # returning false.
42
42
  Boolify = lambda { |value|
43
- case value
44
- when 1
45
- true
46
- when 0
47
- false
48
- else
49
- value
50
- end
43
+ value != 0 unless value.nil?
51
44
  }
52
45
 
53
46
  BoolifySet = lambda { |value|