Skip to content

Commit

Permalink
Merge pull request #1210 from casperisfine/redis-client-0.15
Browse files Browse the repository at this point in the history
Fix compatibility with `redis-client 0.15.0` when using Redis Sentinel
  • Loading branch information
byroot committed Aug 9, 2023
2 parents f21cbca + ef8817e commit f7dfa6b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 27 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,7 @@
# Unreleased

- Fix compatibility with `redis-client 0.15.0` when using Redis Sentinel. Fix #1209.

# 5.0.6

- Wait for an extra `config.read_timeout` in blocking commands rather than an arbitrary 100ms. See #1175.
Expand Down
2 changes: 2 additions & 0 deletions lib/redis.rb
Expand Up @@ -166,6 +166,8 @@ def send_command(command, &block)
@monitor.synchronize do
@client.call_v(command, &block)
end
rescue ::RedisClient::Error => error
Client.translate_error!(error)
end

def send_blocking_command(command, timeout, &block)
Expand Down
44 changes: 22 additions & 22 deletions lib/redis/client.rb
Expand Up @@ -24,7 +24,24 @@ def config(**kwargs)
end

def sentinel(**kwargs)
super(protocol: 2, **kwargs)
super(protocol: 2, **kwargs, client_implementation: ::RedisClient)
end

def translate_error!(error)
redis_error = translate_error_class(error.class)
raise redis_error, error.message, error.backtrace
end

private

def translate_error_class(error_class)
ERROR_MAPPING.fetch(error_class)
rescue IndexError
if (client_error = error_class.ancestors.find { |a| ERROR_MAPPING[a] })
ERROR_MAPPING[error_class] = ERROR_MAPPING[client_error]
else
raise
end
end
end

Expand Down Expand Up @@ -72,7 +89,7 @@ def password
def call_v(command, &block)
super(command, &block)
rescue ::RedisClient::Error => error
translate_error!(error)
Client.translate_error!(error)
end

def blocking_call_v(timeout, command, &block)
Expand All @@ -85,19 +102,19 @@ def blocking_call_v(timeout, command, &block)

super(timeout, command, &block)
rescue ::RedisClient::Error => error
translate_error!(error)
Client.translate_error!(error)
end

def pipelined
super
rescue ::RedisClient::Error => error
translate_error!(error)
Client.translate_error!(error)
end

def multi
super
rescue ::RedisClient::Error => error
translate_error!(error)
Client.translate_error!(error)
end

def disable_reconnection(&block)
Expand All @@ -107,22 +124,5 @@ def disable_reconnection(&block)
def inherit_socket!
@inherit_socket = true
end

private

def translate_error!(error)
redis_error = translate_error_class(error.class)
raise redis_error, error.message, error.backtrace
end

def translate_error_class(error_class)
ERROR_MAPPING.fetch(error_class)
rescue IndexError
if (client_error = error_class.ancestors.find { |a| ERROR_MAPPING[a] })
ERROR_MAPPING[error_class] = ERROR_MAPPING[client_error]
else
raise
end
end
end
end
4 changes: 2 additions & 2 deletions test/redis/client_test.rb
Expand Up @@ -28,10 +28,10 @@ def test_call_raise

def test_error_translate_subclasses
error = Class.new(RedisClient::CommandError)
assert_equal Redis::CommandError, r._client.send(:translate_error_class, error)
assert_equal Redis::CommandError, Redis::Client.send(:translate_error_class, error)

assert_raises KeyError do
r._client.send(:translate_error_class, StandardError)
Redis::Client.send(:translate_error_class, StandardError)
end
end

Expand Down
10 changes: 7 additions & 3 deletions test/sentinel/sentinel_test.rb
Expand Up @@ -197,7 +197,7 @@ def test_sentinel_with_non_sentinel_options
end
end

assert_equal [%w[get-master-addr-by-name master1], ["sentinels", "master1"]], commands[:s1]
assert_equal [%w[auth foo], %w[get-master-addr-by-name master1], ["sentinels", "master1"]], commands[:s1]
assert_equal [%w[auth foo], %w[role]], commands[:m1]
end

Expand Down Expand Up @@ -409,12 +409,15 @@ def test_sentinel_retries

connections = []

fails = Hash.new(0)

handler = lambda do |id, port|
{
sentinel: lambda do |command, *_args|
connections << id

if connections.count(id) < 2
if fails[id] < 2
fails[id] += 1
:close
else
case command
Expand Down Expand Up @@ -451,9 +454,10 @@ def test_sentinel_retries
end
end

assert_equal %i[s1 s2 s1 s1], connections
assert_equal %i[s1 s1 s2 s2 s1 s1], connections

connections.clear
fails.clear

ex = assert_raises(Redis::CannotConnectError) do
RedisMock.start(master) do |master_port|
Expand Down

0 comments on commit f7dfa6b

Please sign in to comment.