Skip to content

Commit 85fa56a

Browse files
committed
wire up retry attempt earlier to handle errors during connection prelude
1 parent 954eab2 commit 85fa56a

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

lib/redis_client.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,7 @@ def ensure_connected(retryable: true)
736736
connection = nil
737737
preferred_error = nil
738738
begin
739-
connection = raw_connection
740-
connection.retry_attempt = config.retriable?(tries) ? tries : nil
739+
connection = raw_connection(config.retriable?(tries) ? tries : nil)
741740
if block_given?
742741
yield connection
743742
else
@@ -776,17 +775,19 @@ def ensure_connected(retryable: true)
776775
end
777776
end
778777

779-
def raw_connection
778+
def raw_connection(retry_attempt = nil)
780779
if @raw_connection.nil? || !@raw_connection.revalidate
781-
connect
780+
connect(retry_attempt)
782781
end
782+
@raw_connection.retry_attempt = retry_attempt
783783
@raw_connection
784784
end
785785

786-
def connect
786+
def connect(retry_attempt = nil)
787787
@pid = PIDCache.pid
788788

789789
if @raw_connection
790+
@raw_connection.retry_attempt = retry_attempt
790791
@middlewares.connect(config) do
791792
@raw_connection.reconnect
792793
end
@@ -799,6 +800,7 @@ def connect
799800
write_timeout: write_timeout,
800801
)
801802
end
803+
@raw_connection.retry_attempt = retry_attempt
802804
end
803805

804806
prelude = config.connection_prelude.dup

lib/redis_client/ruby_connection.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ def write(command)
7676
@io.write(buffer)
7777
rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
7878
raise connection_error(error.message)
79+
rescue Error => error
80+
error._set_config(config)
81+
error._set_retry_attempt(@retry_attempt)
82+
raise error
7983
end
8084
end
8185

@@ -88,6 +92,10 @@ def write_multi(commands)
8892
@io.write(buffer)
8993
rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
9094
raise connection_error(error.message)
95+
rescue Error => error
96+
error._set_config(config)
97+
error._set_retry_attempt(@retry_attempt)
98+
raise error
9199
end
92100
end
93101

@@ -101,6 +109,10 @@ def read(timeout = nil)
101109
raise RedisClient::ProtocolError.with_config(error.message, config)
102110
rescue SystemCallError, IOError, OpenSSL::SSL::SSLError => error
103111
raise connection_error(error.message)
112+
rescue Error => error
113+
error._set_config(config)
114+
error._set_retry_attempt(@retry_attempt)
115+
raise error
104116
end
105117

106118
def measure_round_trip_delay

test/redis_client/middlewares_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,31 @@ def test_final_errors
129129
TestMiddleware.calls.clear
130130
end
131131

132+
def test_final_errors_during_reconnect
133+
client = new_client(reconnect_attempts: 1)
134+
simulate_network_errors(client, ["PING", "HELLO"]) do
135+
assert_raises ConnectionError do
136+
client.call("PING")
137+
end
138+
end
139+
140+
calls = TestMiddleware.calls.select { |type, _| type == :call }
141+
assert_equal 1, calls.size
142+
143+
call = calls[0]
144+
assert_equal :error, call[1]
145+
assert_equal ["PING"], call[2]
146+
refute_predicate call[3], :final?
147+
148+
pipeline_calls = TestMiddleware.calls.select { |type, _| type == :pipeline }
149+
assert_equal 2, pipeline_calls.size
150+
151+
failing_pipeline = pipeline_calls[1]
152+
assert_equal :error, failing_pipeline[1]
153+
assert_equal [["HELLO", "3"]], failing_pipeline[2]
154+
assert_predicate failing_pipeline[3], :final?
155+
end
156+
132157
module DummyMiddleware
133158
def call(command, _config, &_)
134159
command

0 commit comments

Comments
 (0)