1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
# frozen_string_literal: true
require 'redis-client'
class Redis
class Client < ::RedisClient
ERROR_MAPPING = {
RedisClient::ConnectionError => Redis::ConnectionError,
RedisClient::CommandError => Redis::CommandError,
RedisClient::ReadTimeoutError => Redis::TimeoutError,
RedisClient::CannotConnectError => Redis::CannotConnectError,
RedisClient::AuthenticationError => Redis::CannotConnectError,
RedisClient::FailoverError => Redis::CannotConnectError,
RedisClient::PermissionError => Redis::PermissionError,
RedisClient::WrongTypeError => Redis::WrongTypeError,
RedisClient::ReadOnlyError => Redis::ReadOnlyError,
RedisClient::ProtocolError => Redis::ProtocolError,
RedisClient::OutOfMemoryError => Redis::OutOfMemoryError,
}
class << self
def config(**kwargs)
super(protocol: 2, **kwargs)
end
def sentinel(**kwargs)
super(protocol: 2, **kwargs, client_implementation: ::RedisClient)
end
def translate_error!(error, mapping: ERROR_MAPPING)
redis_error = translate_error_class(error.class, mapping: mapping)
raise redis_error, error.message, error.backtrace
end
private
def translate_error_class(error_class, mapping: ERROR_MAPPING)
mapping.fetch(error_class)
rescue IndexError
if (client_error = error_class.ancestors.find { |a| mapping[a] })
mapping[error_class] = mapping[client_error]
else
raise
end
end
end
def id
config.id
end
def server_url
config.server_url
end
def timeout
config.read_timeout
end
def db
config.db
end
def host
config.host unless config.path
end
def port
config.port unless config.path
end
def path
config.path
end
def username
config.username
end
def password
config.password
end
undef_method :call
undef_method :call_once
undef_method :call_once_v
undef_method :blocking_call
def call_v(command, &block)
super(command, &block)
rescue ::RedisClient::Error => error
Client.translate_error!(error)
end
def blocking_call_v(timeout, command, &block)
if timeout && timeout > 0
# Can't use the command timeout argument as the connection timeout
# otherwise it would be very racy. So we add the regular read_timeout on top
# to account for the network delay.
timeout += config.read_timeout
end
super(timeout, command, &block)
rescue ::RedisClient::Error => error
Client.translate_error!(error)
end
def pipelined(exception: true)
super
rescue ::RedisClient::Error => error
Client.translate_error!(error)
end
def multi(watch: nil)
super
rescue ::RedisClient::Error => error
Client.translate_error!(error)
end
def inherit_socket!
@inherit_socket = true
end
end
end
|