redis 5.0.8 → 5.2.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: 68e827844bdac2fa5954e99fd259060a232719927db426788368408b02011eff
4
- data.tar.gz: 46f7f0f74538f29ac4b8f72bc0e2cecaeeea44568174c25d61cf3532869c9f3d
3
+ metadata.gz: 279ebf60fc356e29bbf9872320212da91f48565192b3c6e0d86113bfda5866d9
4
+ data.tar.gz: f152547a2623146e621848ec0fffb376c162220595ca2fba4fc7bbd21cfa0f67
5
5
  SHA512:
6
- metadata.gz: 996e87442dda9f5750a529b9a14627c371b8e042bc6a7c0a5a32d0c36effa24728d10404a983cea0ef07f19c6e6f1571ac75af1d14a5480021445e23a7eb24e5
7
- data.tar.gz: d36cc39b9d847badfe8d63a94ac74ee588a4fa856581e93f113261156be4b6d6e802b207af6fbe526ff7fb3a00b00f27e4f935a2164da18eb329b6eb007dfb4d
6
+ metadata.gz: 48c436c76fedc6951edfee5c5f437bb9ca6aad07fd2eccc8c3c0882bf8c113579df381d947b54e35ce2702254a41494b36f6d8fdae4efa6ba46f8285833b4000
7
+ data.tar.gz: 96a3f2d64afc84175165aa9c1cca3a37c1be04b9f882dba8a30ce350ef0acf52e7d2c4c848ad288257a3ab1e18ca37857307e3b6f9e9e49699498cc00a44fda6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Unreleased
2
2
 
3
+ # 5.2.0
4
+
5
+ - Now require Ruby 2.6 because `redis-client` does.
6
+ - Eagerly close subscribed connection when using `subscribe_with_timeout`. See #1259.
7
+ - Add `exception` flag in `pipelined` allowing failed commands to be returned in the result array when set to `false`.
8
+
9
+ # 5.1.0
10
+
11
+ - `multi` now accept a `watch` keyword argument like `redis-client`. See #1236.
12
+ - `bitcount` and `bitpos` now accept a `scale:` argument on Redis 7+. See #1242
13
+ - Added `expiretime` and `pexpiretime`. See #1248.
14
+
3
15
  # 5.0.8
4
16
 
5
17
  - Fix `Redis#without_reconnect` for sentinel clients. Fix #1212.
data/README.md CHANGED
@@ -191,6 +191,28 @@ end
191
191
  # => ["OK"]
192
192
  ```
193
193
 
194
+ ### Exception management
195
+
196
+ The `exception` flag in the `#pipelined` is a feature that modifies the pipeline execution behavior. When set
197
+ to `false`, it doesn't raise an exception when a command error occurs. Instead, it allows the pipeline to execute all
198
+ commands, and any failed command will be available in the returned array. (Defaults to `true`)
199
+
200
+ ```ruby
201
+ results = redis.pipelined(exception: false) do |pipeline|
202
+ pipeline.set('key1', 'value1')
203
+ pipeline.lpush('key1', 'something') # This will fail
204
+ pipeline.set('key2', 'value2')
205
+ end
206
+ # results => ["OK", #<RedisClient::WrongTypeError: WRONGTYPE Operation against a key holding the wrong kind of value>, "OK"]
207
+
208
+ results.each do |result|
209
+ if result.is_a?(Redis::CommandError)
210
+ # Do something with the failed result
211
+ end
212
+ end
213
+ ```
214
+
215
+
194
216
  ### Executing commands atomically
195
217
 
196
218
  You can use `MULTI/EXEC` to run a number of commands in an atomic
data/lib/redis/client.rb CHANGED
@@ -27,18 +27,18 @@ class Redis
27
27
  super(protocol: 2, **kwargs, client_implementation: ::RedisClient)
28
28
  end
29
29
 
30
- def translate_error!(error)
31
- redis_error = translate_error_class(error.class)
30
+ def translate_error!(error, mapping: ERROR_MAPPING)
31
+ redis_error = translate_error_class(error.class, mapping: mapping)
32
32
  raise redis_error, error.message, error.backtrace
33
33
  end
34
34
 
35
35
  private
36
36
 
37
- def translate_error_class(error_class)
38
- ERROR_MAPPING.fetch(error_class)
37
+ def translate_error_class(error_class, mapping: ERROR_MAPPING)
38
+ mapping.fetch(error_class)
39
39
  rescue IndexError
40
- if (client_error = error_class.ancestors.find { |a| ERROR_MAPPING[a] })
41
- ERROR_MAPPING[error_class] = ERROR_MAPPING[client_error]
40
+ if (client_error = error_class.ancestors.find { |a| mapping[a] })
41
+ mapping[error_class] = mapping[client_error]
42
42
  else
43
43
  raise
44
44
  end
@@ -105,13 +105,13 @@ class Redis
105
105
  Client.translate_error!(error)
106
106
  end
107
107
 
108
- def pipelined
108
+ def pipelined(exception: true)
109
109
  super
110
110
  rescue ::RedisClient::Error => error
111
111
  Client.translate_error!(error)
112
112
  end
113
113
 
114
- def multi
114
+ def multi(watch: nil)
115
115
  super
116
116
  rescue ::RedisClient::Error => error
117
117
  Client.translate_error!(error)
@@ -27,9 +27,13 @@ class Redis
27
27
  # @param [String] key
28
28
  # @param [Integer] start start index
29
29
  # @param [Integer] stop stop index
30
+ # @param [String, Symbol] scale the scale of the offset range
31
+ # e.g. 'BYTE' - interpreted as a range of bytes, 'BIT' - interpreted as a range of bits
30
32
  # @return [Integer] the number of bits set to 1
31
- def bitcount(key, start = 0, stop = -1)
32
- send_command([:bitcount, key, start, stop])
33
+ def bitcount(key, start = 0, stop = -1, scale: nil)
34
+ command = [:bitcount, key, start, stop]
35
+ command << scale if scale
36
+ send_command(command)
33
37
  end
34
38
 
35
39
  # Perform a bitwise operation between strings and store the resulting string in a key.
@@ -51,14 +55,17 @@ class Redis
51
55
  # @param [Integer] bit whether to look for the first 1 or 0 bit
52
56
  # @param [Integer] start start index
53
57
  # @param [Integer] stop stop index
58
+ # @param [String, Symbol] scale the scale of the offset range
59
+ # e.g. 'BYTE' - interpreted as a range of bytes, 'BIT' - interpreted as a range of bits
54
60
  # @return [Integer] the position of the first 1/0 bit.
55
61
  # -1 if looking for 1 and it is not found or start and stop are given.
56
- def bitpos(key, bit, start = nil, stop = nil)
62
+ def bitpos(key, bit, start = nil, stop = nil, scale: nil)
57
63
  raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
58
64
 
59
65
  command = [:bitpos, key, bit]
60
66
  command << start if start
61
67
  command << stop if stop
68
+ command << scale if scale
62
69
  send_command(command)
63
70
  end
64
71
  end
@@ -105,6 +105,14 @@ class Redis
105
105
  send_command(args, &Boolify)
106
106
  end
107
107
 
108
+ # Get a key's expiry time specified as number of seconds from UNIX Epoch
109
+ #
110
+ # @param [String] key
111
+ # @return [Integer] expiry time specified as number of seconds from UNIX Epoch
112
+ def expiretime(key)
113
+ send_command([:expiretime, key])
114
+ end
115
+
108
116
  # Get the time to live (in seconds) for a key.
109
117
  #
110
118
  # @param [String] key
@@ -161,6 +169,14 @@ class Redis
161
169
  send_command(args, &Boolify)
162
170
  end
163
171
 
172
+ # Get a key's expiry time specified as number of milliseconds from UNIX Epoch
173
+ #
174
+ # @param [String] key
175
+ # @return [Integer] expiry time specified as number of milliseconds from UNIX Epoch
176
+ def pexpiretime(key)
177
+ send_command([:pexpiretime, key])
178
+ end
179
+
164
180
  # Get the time to live (in milliseconds) for a key.
165
181
  #
166
182
  # @param [String] key
@@ -130,6 +130,11 @@ class Redis
130
130
  node_for(key).expireat(key, unix_time, **kwargs)
131
131
  end
132
132
 
133
+ # Get the expiration for a key as a UNIX timestamp.
134
+ def expiretime(key)
135
+ node_for(key).expiretime(key)
136
+ end
137
+
133
138
  # Get the time to live (in seconds) for a key.
134
139
  def ttl(key)
135
140
  node_for(key).ttl(key)
@@ -145,6 +150,11 @@ class Redis
145
150
  node_for(key).pexpireat(key, ms_unix_time, **kwarg)
146
151
  end
147
152
 
153
+ # Get the expiration for a key as number of milliseconds from UNIX Epoch.
154
+ def pexpiretime(key)
155
+ node_for(key).pexpiretime(key)
156
+ end
157
+
148
158
  # Get the time to live (in milliseconds) for a key.
149
159
  def pttl(key)
150
160
  node_for(key).pttl(key)
@@ -370,8 +380,8 @@ class Redis
370
380
  end
371
381
 
372
382
  # Count the number of set bits in a range of the string value stored at key.
373
- def bitcount(key, start = 0, stop = -1)
374
- node_for(key).bitcount(key, start, stop)
383
+ def bitcount(key, start = 0, stop = -1, scale: nil)
384
+ node_for(key).bitcount(key, start, stop, scale: scale)
375
385
  end
376
386
 
377
387
  # Perform a bitwise operation between strings and store the resulting string in a key.
@@ -383,8 +393,8 @@ class Redis
383
393
  end
384
394
 
385
395
  # Return the position of the first bit set to 1 or 0 in a string.
386
- def bitpos(key, bit, start = nil, stop = nil)
387
- node_for(key).bitpos(key, bit, start, stop)
396
+ def bitpos(key, bit, start = nil, stop = nil, scale: nil)
397
+ node_for(key).bitpos(key, bit, start, stop, scale: scale)
388
398
  end
389
399
 
390
400
  # Set the string value of a key and return its old value.
@@ -6,9 +6,10 @@ class Redis
6
6
  class PipelinedConnection
7
7
  attr_accessor :db
8
8
 
9
- def initialize(pipeline, futures = [])
9
+ def initialize(pipeline, futures = [], exception: true)
10
10
  @pipeline = pipeline
11
11
  @futures = futures
12
+ @exception = exception
12
13
  end
13
14
 
14
15
  include Commands
@@ -37,7 +38,7 @@ class Redis
37
38
  end
38
39
 
39
40
  def send_command(command, &block)
40
- future = Future.new(command, block)
41
+ future = Future.new(command, block, @exception)
41
42
  @pipeline.call_v(command) do |result|
42
43
  future._set(result)
43
44
  end
@@ -46,7 +47,7 @@ class Redis
46
47
  end
47
48
 
48
49
  def send_blocking_command(command, timeout, &block)
49
- future = Future.new(command, block)
50
+ future = Future.new(command, block, @exception)
50
51
  @pipeline.blocking_call_v(timeout, command) do |result|
51
52
  future._set(result)
52
53
  end
@@ -79,10 +80,11 @@ class Redis
79
80
  class Future < BasicObject
80
81
  FutureNotReady = ::Redis::FutureNotReady.new
81
82
 
82
- def initialize(command, coerce)
83
+ def initialize(command, coerce, exception)
83
84
  @command = command
84
85
  @object = FutureNotReady
85
86
  @coerce = coerce
87
+ @exception = exception
86
88
  end
87
89
 
88
90
  def inspect
@@ -95,7 +97,7 @@ class Redis
95
97
  end
96
98
 
97
99
  def value
98
- ::Kernel.raise(@object) if @object.is_a?(::StandardError)
100
+ ::Kernel.raise(@object) if @exception && @object.is_a?(::StandardError)
99
101
  @object
100
102
  end
101
103
 
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.0.8'
4
+ VERSION = '5.2.0'
5
5
  end
data/lib/redis.rb CHANGED
@@ -99,10 +99,10 @@ class Redis
99
99
  @client
100
100
  end
101
101
 
102
- def pipelined
102
+ def pipelined(exception: true)
103
103
  synchronize do |client|
104
- client.pipelined do |raw_pipeline|
105
- yield PipelinedConnection.new(raw_pipeline)
104
+ client.pipelined(exception: exception) do |raw_pipeline|
105
+ yield PipelinedConnection.new(raw_pipeline, exception: exception)
106
106
  end
107
107
  end
108
108
  end
@@ -175,6 +175,7 @@ class Redis
175
175
  @subscription_client.send(method, *channels, &block)
176
176
  end
177
177
  ensure
178
+ @subscription_client&.close
178
179
  @subscription_client = nil
179
180
  end
180
181
  else
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.0.8
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2023-10-23 00:00:00.000000000 Z
19
+ date: 2024-04-15 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: redis-client
@@ -24,14 +24,14 @@ dependencies:
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 0.17.0
27
+ version: 0.22.0
28
28
  type: :runtime
29
29
  prerelease: false
30
30
  version_requirements: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 0.17.0
34
+ version: 0.22.0
35
35
  description: |2
36
36
  A Ruby client that tries to match Redis' API one-to-one, while still
37
37
  providing an idiomatic interface.
@@ -75,9 +75,9 @@ licenses:
75
75
  metadata:
76
76
  bug_tracker_uri: https://github.com/redis/redis-rb/issues
77
77
  changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
78
- documentation_uri: https://www.rubydoc.info/gems/redis/5.0.8
78
+ documentation_uri: https://www.rubydoc.info/gems/redis/5.2.0
79
79
  homepage_uri: https://github.com/redis/redis-rb
80
- source_code_uri: https://github.com/redis/redis-rb/tree/v5.0.8
80
+ source_code_uri: https://github.com/redis/redis-rb/tree/v5.2.0
81
81
  post_install_message:
82
82
  rdoc_options: []
83
83
  require_paths:
@@ -86,14 +86,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 2.5.0
89
+ version: 2.6.0
90
90
  required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - ">="
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  requirements: []
96
- rubygems_version: 3.3.7
96
+ rubygems_version: 3.5.3
97
97
  signing_key:
98
98
  specification_version: 4
99
99
  summary: A Ruby client library for Redis