redis 5.2.0 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 279ebf60fc356e29bbf9872320212da91f48565192b3c6e0d86113bfda5866d9
4
- data.tar.gz: f152547a2623146e621848ec0fffb376c162220595ca2fba4fc7bbd21cfa0f67
3
+ metadata.gz: 485e29928983863d4725f47cf52718493c36724b1b736951603fb81648fd1ffb
4
+ data.tar.gz: 17663d08f23fe1106e89f3b06805402f5f1ff7b5bcee2e4bb9593cc3329646f7
5
5
  SHA512:
6
- metadata.gz: 48c436c76fedc6951edfee5c5f437bb9ca6aad07fd2eccc8c3c0882bf8c113579df381d947b54e35ce2702254a41494b36f6d8fdae4efa6ba46f8285833b4000
7
- data.tar.gz: 96a3f2d64afc84175165aa9c1cca3a37c1be04b9f882dba8a30ce350ef0acf52e7d2c4c848ad288257a3ab1e18ca37857307e3b6f9e9e49699498cc00a44fda6
6
+ metadata.gz: 71bed198d46e435677b3ebf725ba65a55af5d5d7a73ff1593d2ac7044972d2898f7c5503fc69d3aa202d8a00781174e0c7348cefa06102c948b9df19cd22d81c
7
+ data.tar.gz: 607288d9a58459346db9c6e79041d35c98cc2c3268c74ffceecd395799833b9ba8e0f1c29c236d6c5afdc917bd66089721fdf5977efcab0799f46cfedb18e826
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Unreleased
2
2
 
3
+ # 5.4.0
4
+
5
+ - Fix `blmpop` method to actually use `BLMPOP`, it was mistakenly issuing `LMPOP` commands.
6
+ - `xadd` now accepts a `minid:` argument.
7
+ - `zrank` and `zrevrank` now accepts `with_score:` argument.
8
+ - `Redis#call` now accept a block, allowing to use `Redis` instances where `RedisClient` is expected.
9
+
10
+ # 5.3.0
11
+
12
+ - Fix the return type of `hgetall` when used inside a `multi` transaction which is itself inside a pipeline.
13
+
3
14
  # 5.2.0
4
15
 
5
16
  - Now require Ruby 2.6 because `redis-client` does.
data/README.md CHANGED
@@ -34,7 +34,7 @@ You can also specify connection options as a [`redis://` URL][redis-url]:
34
34
  redis = Redis.new(url: "redis://:p4ssw0rd@10.0.1.1:6380/15")
35
35
  ```
36
36
 
37
- The client expects passwords with special chracters to be URL-encoded (i.e.
37
+ The client expects passwords with special characters to be URL-encoded (i.e.
38
38
  `CGI.escape(password)`).
39
39
 
40
40
  To connect to Redis listening on a Unix socket, try:
@@ -77,7 +77,7 @@ The client does not provide connection pooling. Each `Redis` instance
77
77
  has one and only one connection to the server, and use of this connection
78
78
  is protected by a mutex.
79
79
 
80
- As such it is heavilly recommended to use the [`connection_pool` gem](https://github.com/mperham/connection_pool), e.g.:
80
+ As such it is heavily recommended to use the [`connection_pool` gem](https://github.com/mperham/connection_pool), e.g.:
81
81
 
82
82
  ```ruby
83
83
  module MyApp
@@ -139,7 +139,7 @@ SENTINELS = [{ host: '127.0.0.1', port: 26380 },
139
139
  redis = Redis.new(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret')
140
140
  ```
141
141
 
142
- So you have to provide Sentinel credential and Redis explictly even they are the same
142
+ So you have to provide Sentinel credential and Redis explicitly even they are the same
143
143
 
144
144
  ```ruby
145
145
  # Use 'mysecret' to authenticate against the mymaster instance and sentinel
@@ -273,6 +273,7 @@ See lib/redis/errors.rb for information about what exceptions are possible.
273
273
  ## Timeouts
274
274
 
275
275
  The client allows you to configure connect, read, and write timeouts.
276
+ Starting in version 5.0, the default for each is 1. Before that, it was 5.
276
277
  Passing a single `timeout` option will set all three values:
277
278
 
278
279
  ```ruby
@@ -405,7 +406,7 @@ gem "hiredis-client"
405
406
  ```
406
407
 
407
408
  If your application doesn't call `Bundler.require`, you may have
408
- to require it explictly:
409
+ to require it explicitly:
409
410
 
410
411
  ```ruby
411
412
  require "hiredis-client"
@@ -222,6 +222,8 @@ class Redis
222
222
  # - `:count => Integer`: return count keys at most per iteration
223
223
  #
224
224
  # @return [String, Array<[String, String]>] the next cursor and all found keys
225
+ #
226
+ # See the [Redis Server HSCAN documentation](https://redis.io/docs/latest/commands/hscan/) for further details
225
227
  def hscan(key, cursor, **options)
226
228
  _scan(:hscan, cursor, [key], **options) do |reply|
227
229
  [reply[0], reply[1].each_slice(2).to_a]
@@ -239,6 +241,8 @@ class Redis
239
241
  # - `:count => Integer`: return count keys at most per iteration
240
242
  #
241
243
  # @return [Enumerator] an enumerator for all found keys
244
+ #
245
+ # See the [Redis Server HSCAN documentation](https://redis.io/docs/latest/commands/hscan/) for further details
242
246
  def hscan_each(key, **options, &block)
243
247
  return to_enum(:hscan_each, key, **options) unless block_given?
244
248
 
@@ -22,6 +22,8 @@ class Redis
22
22
  # - `:type => String`: return keys only of the given type
23
23
  #
24
24
  # @return [String, Array<String>] the next cursor and all found keys
25
+ #
26
+ # See the [Redis Server SCAN documentation](https://redis.io/docs/latest/commands/scan/) for further details
25
27
  def scan(cursor, **options)
26
28
  _scan(:scan, cursor, [], **options)
27
29
  end
@@ -46,6 +48,8 @@ class Redis
46
48
  # - `:type => String`: return keys only of the given type
47
49
  #
48
50
  # @return [Enumerator] an enumerator for all found keys
51
+ #
52
+ # See the [Redis Server SCAN documentation](https://redis.io/docs/latest/commands/scan/) for further details
49
53
  def scan_each(**options, &block)
50
54
  return to_enum(:scan_each, **options) unless block_given?
51
55
 
@@ -282,6 +286,8 @@ class Redis
282
286
  #
283
287
  # @param [String] pattern
284
288
  # @return [Array<String>]
289
+ #
290
+ # See the [Redis Server KEYS documentation](https://redis.io/docs/latest/commands/keys/) for further details
285
291
  def keys(pattern = "*")
286
292
  send_command([:keys, pattern]) do |reply|
287
293
  if reply.is_a?(String)
@@ -205,7 +205,7 @@ class Redis
205
205
  def blmpop(timeout, *keys, modifier: "LEFT", count: nil)
206
206
  raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT"
207
207
 
208
- args = [:lmpop, keys.size, *keys, modifier]
208
+ args = [:blmpop, timeout, keys.size, *keys, modifier]
209
209
  args << "COUNT" << Integer(count) if count
210
210
 
211
211
  send_blocking_command(args, timeout)
@@ -29,17 +29,23 @@ class Redis
29
29
  end
30
30
 
31
31
  # Listen for messages published to channels matching the given patterns.
32
+ # See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
33
+ # for further details
32
34
  def psubscribe(*channels, &block)
33
35
  _subscription(:psubscribe, 0, channels, block)
34
36
  end
35
37
 
36
38
  # Listen for messages published to channels matching the given patterns.
37
39
  # Throw a timeout error if there is no messages for a timeout period.
40
+ # See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
41
+ # for further details
38
42
  def psubscribe_with_timeout(timeout, *channels, &block)
39
43
  _subscription(:psubscribe_with_timeout, timeout, channels, block)
40
44
  end
41
45
 
42
46
  # Stop listening for messages posted to channels matching the given patterns.
47
+ # See the [Redis Server PUNSUBSCRIBE documentation](https://redis.io/docs/latest/commands/punsubscribe/)
48
+ # for further details
43
49
  def punsubscribe(*channels)
44
50
  _subscription(:punsubscribe, 0, channels, nil)
45
51
  end
@@ -184,6 +184,8 @@ class Redis
184
184
  # - `:count => Integer`: return count keys at most per iteration
185
185
  #
186
186
  # @return [String, Array<String>] the next cursor and all found members
187
+ #
188
+ # See the [Redis Server SSCAN documentation](https://redis.io/docs/latest/commands/sscan/) for further details
187
189
  def sscan(key, cursor, **options)
188
190
  _scan(:sscan, cursor, [key], **options)
189
191
  end
@@ -199,6 +201,8 @@ class Redis
199
201
  # - `:count => Integer`: return count keys at most per iteration
200
202
  #
201
203
  # @return [Enumerator] an enumerator for all keys in the set
204
+ #
205
+ # See the [Redis Server SSCAN documentation](https://redis.io/docs/latest/commands/sscan/) for further details
202
206
  def sscan_each(key, **options, &block)
203
207
  return to_enum(:sscan_each, key, **options) unless block_given?
204
208
 
@@ -454,21 +454,55 @@ class Redis
454
454
 
455
455
  # Determine the index of a member in a sorted set.
456
456
  #
457
+ # @example Retrieve member rank
458
+ # redis.zrank("zset", "a")
459
+ # # => 3
460
+ # @example Retrieve member rank with their score
461
+ # redis.zrank("zset", "a", :with_score => true)
462
+ # # => [3, 32.0]
463
+ #
457
464
  # @param [String] key
458
465
  # @param [String] member
459
- # @return [Integer]
460
- def zrank(key, member)
461
- send_command([:zrank, key, member])
466
+ #
467
+ # @return [Integer, [Integer, Float]]
468
+ # - when `:with_score` is not specified, an Integer
469
+ # - when `:with_score` is specified, a `[rank, score]` pair
470
+ def zrank(key, member, withscore: false, with_score: withscore)
471
+ args = [:zrank, key, member]
472
+
473
+ if with_score
474
+ args << "WITHSCORE"
475
+ block = FloatifyPair
476
+ end
477
+
478
+ send_command(args, &block)
462
479
  end
463
480
 
464
481
  # Determine the index of a member in a sorted set, with scores ordered from
465
482
  # high to low.
466
483
  #
484
+ # @example Retrieve member rank
485
+ # redis.zrevrank("zset", "a")
486
+ # # => 3
487
+ # @example Retrieve member rank with their score
488
+ # redis.zrevrank("zset", "a", :with_score => true)
489
+ # # => [3, 32.0]
490
+ #
467
491
  # @param [String] key
468
492
  # @param [String] member
469
- # @return [Integer]
470
- def zrevrank(key, member)
471
- send_command([:zrevrank, key, member])
493
+ #
494
+ # @return [Integer, [Integer, Float]]
495
+ # - when `:with_score` is not specified, an Integer
496
+ # - when `:with_score` is specified, a `[rank, score]` pair
497
+ def zrevrank(key, member, withscore: false, with_score: withscore)
498
+ args = [:zrevrank, key, member]
499
+
500
+ if with_score
501
+ args << "WITHSCORE"
502
+ block = FloatifyPair
503
+ end
504
+
505
+ send_command(args, &block)
472
506
  end
473
507
 
474
508
  # Remove all members in a sorted set within the given indexes.
@@ -817,6 +851,8 @@ class Redis
817
851
  #
818
852
  # @return [String, Array<[String, Float]>] the next cursor and all found
819
853
  # members and scores
854
+ #
855
+ # See the [Redis Server ZSCAN documentation](https://redis.io/docs/latest/commands/zscan/) for further details
820
856
  def zscan(key, cursor, **options)
821
857
  _scan(:zscan, cursor, [key], **options) do |reply|
822
858
  [reply[0], FloatifyPairs.call(reply[1])]
@@ -834,6 +870,8 @@ class Redis
834
870
  # - `:count => Integer`: return count keys at most per iteration
835
871
  #
836
872
  # @return [Enumerator] an enumerator for all found scores and members
873
+ #
874
+ # See the [Redis Server ZSCAN documentation](https://redis.io/docs/latest/commands/zscan/) for further details
837
875
  def zscan_each(key, **options, &block)
838
876
  return to_enum(:zscan_each, key, **options) unless block_given?
839
877
 
@@ -41,18 +41,25 @@ class Redis
41
41
  # @param opts [Hash] several options for `XADD` command
42
42
  #
43
43
  # @option opts [String] :id the entry id, default value is `*`, it means auto generation
44
- # @option opts [Integer] :maxlen max length of entries
45
- # @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
44
+ # @option opts [Integer] :maxlen max length of entries to keep
45
+ # @option opts [Integer] :minid min id of entries to keep
46
+ # @option opts [Boolean] :approximate whether to add `~` modifier of maxlen/minid or not
46
47
  # @option opts [Boolean] :nomkstream whether to add NOMKSTREAM, default is not to add
47
48
  #
48
49
  # @return [String] the entry id
49
- def xadd(key, entry, approximate: nil, maxlen: nil, nomkstream: nil, id: '*')
50
+ def xadd(key, entry, approximate: nil, maxlen: nil, minid: nil, nomkstream: nil, id: '*')
50
51
  args = [:xadd, key]
51
52
  args << 'NOMKSTREAM' if nomkstream
52
53
  if maxlen
54
+ raise ArgumentError, "can't supply both maxlen and minid" if minid
55
+
53
56
  args << "MAXLEN"
54
57
  args << "~" if approximate
55
58
  args << maxlen
59
+ elsif minid
60
+ args << "MINID"
61
+ args << "~" if approximate
62
+ args << minid
56
63
  end
57
64
  args << id
58
65
  args.concat(entry.flatten)
@@ -83,12 +83,14 @@ class Redis
83
83
  end
84
84
  }
85
85
 
86
+ FloatifyPair = lambda { |(first, score)|
87
+ [first, Floatify.call(score)]
88
+ }
89
+
86
90
  FloatifyPairs = lambda { |value|
87
91
  return value unless value.respond_to?(:each_slice)
88
92
 
89
- value.each_slice(2).map do |member, score|
90
- [member, Floatify.call(score)]
91
- end
93
+ value.each_slice(2).map(&FloatifyPair)
92
94
  }
93
95
 
94
96
  HashifyInfo = lambda { |reply|
@@ -199,8 +201,8 @@ class Redis
199
201
  # hash, are up to consumers.
200
202
  #
201
203
  # Redis error replies are raised as Ruby exceptions.
202
- def call(*command)
203
- send_command(command)
204
+ def call(*command, &block)
205
+ send_command(command, &block)
204
206
  end
205
207
 
206
208
  # Interact with the sentinel command (masters, master, slaves, failover)
@@ -752,14 +752,14 @@ class Redis
752
752
  end
753
753
 
754
754
  # Determine the index of a member in a sorted set.
755
- def zrank(key, member)
756
- node_for(key).zrank(key, member)
755
+ def zrank(key, member, **options)
756
+ node_for(key).zrank(key, member, **options)
757
757
  end
758
758
 
759
759
  # Determine the index of a member in a sorted set, with scores ordered from
760
760
  # high to low.
761
- def zrevrank(key, member)
762
- node_for(key).zrevrank(key, member)
761
+ def zrevrank(key, member, **options)
762
+ node_for(key).zrevrank(key, member, **options)
763
763
  end
764
764
 
765
765
  # Remove all members in a sorted set within the given indexes.
@@ -948,12 +948,16 @@ class Redis
948
948
  end
949
949
 
950
950
  # Listen for messages published to channels matching the given patterns.
951
+ # See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
952
+ # for further details
951
953
  def psubscribe(*channels, &block)
952
954
  raise NotImplementedError
953
955
  end
954
956
 
955
957
  # Stop listening for messages posted to channels matching the given
956
958
  # patterns.
959
+ # See the [Redis Server PUNSUBSCRIBE documentation](https://redis.io/docs/latest/commands/punsubscribe/)
960
+ # for further details
957
961
  def punsubscribe(*channels)
958
962
  raise NotImplementedError
959
963
  end
@@ -58,7 +58,7 @@ class Redis
58
58
 
59
59
  class MultiConnection < PipelinedConnection
60
60
  def multi
61
- raise Redis::Error, "Can't nest multi transaction"
61
+ raise Redis::BaseError, "Can't nest multi transaction"
62
62
  end
63
63
 
64
64
  private
@@ -118,12 +118,14 @@ class Redis
118
118
  end
119
119
 
120
120
  def _set(replies)
121
- if replies
122
- @futures.each_with_index do |future, index|
121
+ @object = if replies
122
+ @futures.map.with_index do |future, index|
123
123
  future._set(replies[index])
124
+ future.value
124
125
  end
126
+ else
127
+ replies
125
128
  end
126
- @object = replies
127
129
  end
128
130
  end
129
131
  end
data/lib/redis/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Redis
4
- VERSION = '5.2.0'
4
+ VERSION = '5.4.0'
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: 5.2.0
4
+ version: 5.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -13,10 +13,9 @@ authors:
13
13
  - Michel Martens
14
14
  - Damian Janowski
15
15
  - Pieter Noordhuis
16
- autorequire:
17
16
  bindir: bin
18
17
  cert_chain: []
19
- date: 2024-04-15 00:00:00.000000000 Z
18
+ date: 2025-02-20 00:00:00.000000000 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: redis-client
@@ -75,10 +74,9 @@ licenses:
75
74
  metadata:
76
75
  bug_tracker_uri: https://github.com/redis/redis-rb/issues
77
76
  changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
78
- documentation_uri: https://www.rubydoc.info/gems/redis/5.2.0
77
+ documentation_uri: https://www.rubydoc.info/gems/redis/5.4.0
79
78
  homepage_uri: https://github.com/redis/redis-rb
80
- source_code_uri: https://github.com/redis/redis-rb/tree/v5.2.0
81
- post_install_message:
79
+ source_code_uri: https://github.com/redis/redis-rb/tree/v5.4.0
82
80
  rdoc_options: []
83
81
  require_paths:
84
82
  - lib
@@ -93,8 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
91
  - !ruby/object:Gem::Version
94
92
  version: '0'
95
93
  requirements: []
96
- rubygems_version: 3.5.3
97
- signing_key:
94
+ rubygems_version: 3.6.2
98
95
  specification_version: 4
99
96
  summary: A Ruby client library for Redis
100
97
  test_files: []