redis-client 0.25.3 → 0.26.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: c9d414e733ddfec002eb356535edebdca59f5dc95bb028ab9012ef7490708ef8
4
- data.tar.gz: 829dd355a87f34c5dd94da685839be29cb23755c9eb420ee4fcf4faef557c741
3
+ metadata.gz: f265ac0d87bb764ab0e577f3ef0440b155de0ba2d88d44469167a634eebd03bb
4
+ data.tar.gz: 6edcf258e079c1123587e2f670793bd64dd38ada6116c31ddf992a328f015ecd
5
5
  SHA512:
6
- metadata.gz: bbf68e7d8643165a1a7658a65774e0046e5c0e86338c91850f5c50292e3ba5bd2a8d9d4b124b95c722e5fb99844329bb8d1b42f4f5044c7f2e0db0a58f1f2add
7
- data.tar.gz: 6416e379d6858466d93fae1861f446632cebe8bbdcda483add50c480f99856c1419d24a076fd12f76c921a9b5338850dc88b3bb30ab3edb683ba40935fd688bd
6
+ metadata.gz: dfd46c41eca304f6b438da604089e51719239c0e72a3658a464c1f769fa14b005415e105cc2765a98f3e708b41fa39073ed5d982539fa58a465f391c7f3d40fd
7
+ data.tar.gz: 2b2180f10bf25af818729ccce4724d378a03cb009361fb76c5b704c0171ca19c66766878e375f5f4e483f1b604c3e5ff8ca29ffe7495aa15ca0b2c3f5a4c0b7e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.26.0
4
+
5
+ - Add `RedisClient::Error#final?` and `#retriable?` to allow middleware to filter out non-final errors.
6
+ - Fix precedence of `db: nil` initialization parameter.
7
+
8
+ ```ruby
9
+ Redis.new(url: "redis://localhost:6379/3", db: nil).db
10
+ ```
11
+
12
+ Before: `0`
13
+ After: `3`
14
+
3
15
  # 0.25.3
4
16
 
5
17
  - Fix `hiredis-client` compilation with `clang 21`.
@@ -205,7 +217,7 @@
205
217
  - Added `_v` versions of `call` methods to make it easier to pass commands as arrays without splating.
206
218
  - Fix calling `blocking_call` with a block in a pipeline.
207
219
  - `blocking_call` now raise `ReadTimeoutError` if the command didn't complete in time.
208
- - Fix `blocking_call` to not respect `retry_attempts` on timeout.
220
+ - Fix `blocking_call` to not respect `reconnect_attempts` on timeout.
209
221
  - Stop parsing RESP3 sets as Ruby Set instances.
210
222
  - Fix `SystemStackError` when parsing very large hashes. Fix: #30
211
223
  - `hiredis` now more properly release the GVL when doing IOs.
data/README.md CHANGED
@@ -459,6 +459,29 @@ RedisClient.register(MyGlobalRedisInstrumentation)
459
459
 
460
460
  redis_config = RedisClient.config(custom: { tags: { "environment": Rails.env }})
461
461
  ```
462
+
463
+ ### Instrumenting Errors
464
+
465
+ It is important to note that when `reconnect_attempts` is enabled, all network errors are reported to the middlewares,
466
+ even the ones that will be retried.
467
+
468
+ In many cases you may want to ignore retriable errors, or report them differently:
469
+
470
+ ```ruby
471
+ module MyGlobalRedisInstrumentation
472
+ def call(command, redis_config)
473
+ super
474
+ rescue RedisClient::Error => error
475
+ if error.final?
476
+ # Error won't be retried.
477
+ else
478
+ # Error will be retried.
479
+ end
480
+ raise
481
+ end
482
+ end
483
+ ```
484
+
462
485
  ### Timeouts
463
486
 
464
487
  The client allows you to configure connect, read, and write timeouts.
@@ -140,6 +140,10 @@ class RedisClient
140
140
  @client_implementation.new(self, **kwargs)
141
141
  end
142
142
 
143
+ def retriable?(attempt)
144
+ @reconnect_attempts && @reconnect_attempts[attempt]
145
+ end
146
+
143
147
  def retry_connecting?(attempt, _error)
144
148
  if @reconnect_attempts
145
149
  if (pause = @reconnect_attempts[attempt])
@@ -191,14 +195,15 @@ class RedisClient
191
195
  path: nil,
192
196
  username: nil,
193
197
  password: nil,
198
+ db: nil,
194
199
  **kwargs
195
200
  )
196
201
  if url
197
202
  url_config = URLConfig.new(url)
198
203
  kwargs = {
199
204
  ssl: url_config.ssl?,
200
- db: url_config.db,
201
205
  }.compact.merge(kwargs)
206
+ db ||= url_config.db
202
207
  host ||= url_config.host
203
208
  port ||= url_config.port
204
209
  path ||= url_config.path
@@ -206,7 +211,7 @@ class RedisClient
206
211
  password ||= url_config.password
207
212
  end
208
213
 
209
- super(username: username, password: password, **kwargs)
214
+ super(username: username, password: password, db: db, **kwargs)
210
215
 
211
216
  if @path = path
212
217
  @host = nil
@@ -2,8 +2,11 @@
2
2
 
3
3
  class RedisClient
4
4
  module ConnectionMixin
5
+ attr_accessor :retry_attempt
6
+
5
7
  def initialize
6
8
  @pending_reads = 0
9
+ @retry_attempt = nil
7
10
  end
8
11
 
9
12
  def reconnect
@@ -33,6 +36,7 @@ class RedisClient
33
36
  if result.is_a?(Error)
34
37
  result._set_command(command)
35
38
  result._set_config(config)
39
+ result._set_retry_attempt(@retry_attempt)
36
40
  raise result
37
41
  else
38
42
  result
@@ -61,6 +65,7 @@ class RedisClient
61
65
  elsif result.is_a?(Error)
62
66
  result._set_command(commands[index])
63
67
  result._set_config(config)
68
+ result._set_retry_attempt(@retry_attempt)
64
69
  first_exception ||= result
65
70
  end
66
71
 
@@ -82,5 +87,15 @@ class RedisClient
82
87
  # to account for the network delay.
83
88
  timeout + config.read_timeout
84
89
  end
90
+
91
+ def protocol_error(message)
92
+ ProtocolError.with_config(message, config)
93
+ end
94
+
95
+ def connection_error(message)
96
+ error = ConnectionError.with_config(message, config)
97
+ error._set_retry_attempt(@retry_attempt)
98
+ error
99
+ end
85
100
  end
86
101
  end
@@ -75,7 +75,7 @@ class RedisClient
75
75
  begin
76
76
  @io.write(buffer)
77
77
  rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
78
- raise ConnectionError.with_config(error.message, config)
78
+ raise connection_error(error.message)
79
79
  end
80
80
  end
81
81
 
@@ -87,7 +87,7 @@ class RedisClient
87
87
  begin
88
88
  @io.write(buffer)
89
89
  rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
90
- raise ConnectionError.with_config(error.message, config)
90
+ raise connection_error(error.message)
91
91
  end
92
92
  end
93
93
 
@@ -100,7 +100,7 @@ class RedisClient
100
100
  rescue RedisClient::RESP3::UnknownType => error
101
101
  raise RedisClient::ProtocolError.with_config(error.message, config)
102
102
  rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
103
- raise ConnectionError.with_config(error.message, config)
103
+ raise connection_error(error.message)
104
104
  end
105
105
 
106
106
  def measure_round_trip_delay
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class RedisClient
4
- VERSION = "0.25.3"
4
+ VERSION = "0.26.0"
5
5
  end
data/lib/redis_client.rb CHANGED
@@ -99,13 +99,32 @@ class RedisClient
99
99
  end
100
100
  end
101
101
 
102
+ module Retriable
103
+ def _set_retry_attempt(retry_attempt)
104
+ @retry_attempt = retry_attempt
105
+ end
106
+
107
+ def retry_attempt
108
+ @retry_attempt || 0
109
+ end
110
+
111
+ def retriable?
112
+ !!@retry_attempt
113
+ end
114
+
115
+ def final?
116
+ !@retry_attempt
117
+ end
118
+ end
119
+
102
120
  class Error < StandardError
103
121
  include HasConfig
122
+ include Retriable
104
123
 
105
124
  def self.with_config(message, config = nil)
106
- new(message).tap do |error|
107
- error._set_config(config)
108
- end
125
+ error = new(message)
126
+ error._set_config(config)
127
+ error
109
128
  end
110
129
  end
111
130
 
@@ -706,6 +725,7 @@ class RedisClient
706
725
  close if !config.inherit_socket && @pid != PIDCache.pid
707
726
 
708
727
  if @disable_reconnection
728
+ @raw_connection.retry_attempt = nil
709
729
  if block_given?
710
730
  yield @raw_connection
711
731
  else
@@ -717,6 +737,7 @@ class RedisClient
717
737
  preferred_error = nil
718
738
  begin
719
739
  connection = raw_connection
740
+ connection.retry_attempt = config.retriable?(tries) ? tries : nil
720
741
  if block_given?
721
742
  yield connection
722
743
  else
@@ -744,6 +765,7 @@ class RedisClient
744
765
  connection = ensure_connected
745
766
  begin
746
767
  @disable_reconnection = true
768
+ @raw_connection.retry_attempt = nil
747
769
  yield connection
748
770
  rescue ConnectionError, ProtocolError
749
771
  close
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.3
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
70
  - !ruby/object:Gem::Version
71
71
  version: '0'
72
72
  requirements: []
73
- rubygems_version: 3.7.1
73
+ rubygems_version: 3.6.9
74
74
  specification_version: 4
75
75
  summary: Simple low-level client for Redis 6+
76
76
  test_files: []