Class: Redis::Client
- Inherits:
-
RedisClient
- Object
- RedisClient
- Redis::Client
- Defined in:
- lib/redis/client.rb
Constant Summary collapse
- 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 Method Summary collapse
- .config(protocol: 3, **kwargs) ⇒ Object
-
.resp3_unsupported?(error) ⇒ Boolean
Whether
errorraised during the connection handshake means the server can't speak RESP3 (so we should retry the connection as RESP2). - .sentinel(protocol: 3, **kwargs) ⇒ Object
- .translate_error!(error, mapping: ERROR_MAPPING) ⇒ Object
Instance Method Summary collapse
- #blocking_call_v(timeout, command, &block) ⇒ Object
-
#call_v(command, &block) ⇒ Object
We default to RESP3.
- #db ⇒ Object
- #host ⇒ Object
- #id ⇒ Object
- #inherit_socket! ⇒ Object
- #multi(watch: nil) ⇒ Object
- #password ⇒ Object
- #path ⇒ Object
- #pipelined(exception: true) ⇒ Object
- #port ⇒ Object
- #protocol ⇒ Object
- #server_url ⇒ Object
- #timeout ⇒ Object
- #username ⇒ Object
Class Method Details
.config(protocol: 3, **kwargs) ⇒ Object
23 24 25 26 |
# File 'lib/redis/client.rb', line 23 def config(protocol: 3, **kwargs) super(protocol: protocol, **kwargs, driver_info: Redis::LibIdentity.driver_info(kwargs[:driver_info])) end |
.resp3_unsupported?(error) ⇒ Boolean
Whether error raised during the connection handshake means the server can't speak RESP3
(so we should retry the connection as RESP2). Covers Redis < 6 (no HELLO command, surfaced
by redis-client as UnsupportedServer) and any server replying NOPROTO to HELLO 3.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/redis/client.rb', line 42 def resp3_unsupported?(error) return true if error.is_a?(::RedisClient::UnsupportedServer) return true if error.is_a?(::RedisClient::CommandError) && error..include?("NOPROTO") # Redis::Cluster discovers its topology by connecting to each startup node. When those nodes # don't speak RESP3, redis-cluster-client collects the per-node failures and re-raises them # wrapped in an InitialSetupError, discarding the original error classes (see # RedisClient::Cluster::InitialSetupError.from_errors). Only the concatenated message # survives, so match it to still trigger the RESP2 fallback for pre-6.0 clusters. Guarded by # defined? because the cluster error class is only loaded with the redis-clustering gem. defined?(::RedisClient::Cluster::InitialSetupError) && error.is_a?(::RedisClient::Cluster::InitialSetupError) && (error..include?("NOPROTO") || error..include?("HELLO command")) end |
.sentinel(protocol: 3, **kwargs) ⇒ Object
28 29 30 31 32 |
# File 'lib/redis/client.rb', line 28 def sentinel(protocol: 3, **kwargs) super(protocol: protocol, **kwargs, driver_info: Redis::LibIdentity.driver_info(kwargs[:driver_info]), client_implementation: ::RedisClient) end |
.translate_error!(error, mapping: ERROR_MAPPING) ⇒ Object
34 35 36 37 |
# File 'lib/redis/client.rb', line 34 def translate_error!(error, mapping: ERROR_MAPPING) redis_error = translate_error_class(error.class, mapping: mapping) raise redis_error, error., error.backtrace end |
Instance Method Details
#blocking_call_v(timeout, command, &block) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/redis/client.rb', line 128 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 raise if Client.resp3_unsupported?(error) Client.translate_error!(error) end |
#call_v(command, &block) ⇒ Object
We default to RESP3. Servers that can't speak it reject the HELLO 3 handshake (Redis < 6.0
has no HELLO at all; others answer NOPROTO). Re-raise those errors untranslated so they reach
Redis#with_protocol_fallback as RedisClient::Error and trigger a transparent rebuild as RESP2 —
the same path the sentinel and cluster clients already use. Everything else is translated to
the matching Redis::* error.
120 121 122 123 124 125 126 |
# File 'lib/redis/client.rb', line 120 def call_v(command, &block) super(command, &block) rescue ::RedisClient::Error => error raise if Client.resp3_unsupported?(error) Client.translate_error!(error) end |
#db ⇒ Object
82 83 84 |
# File 'lib/redis/client.rb', line 82 def db config.db end |
#host ⇒ Object
90 91 92 |
# File 'lib/redis/client.rb', line 90 def host config.host unless config.path end |
#id ⇒ Object
70 71 72 |
# File 'lib/redis/client.rb', line 70 def id config.id end |
#inherit_socket! ⇒ Object
159 160 161 |
# File 'lib/redis/client.rb', line 159 def inherit_socket! @inherit_socket = true end |
#multi(watch: nil) ⇒ Object
151 152 153 154 155 156 157 |
# File 'lib/redis/client.rb', line 151 def multi(watch: nil) super rescue ::RedisClient::Error => error raise if Client.resp3_unsupported?(error) Client.translate_error!(error) end |
#password ⇒ Object
106 107 108 |
# File 'lib/redis/client.rb', line 106 def password config.password end |
#path ⇒ Object
98 99 100 |
# File 'lib/redis/client.rb', line 98 def path config.path end |
#pipelined(exception: true) ⇒ Object
143 144 145 146 147 148 149 |
# File 'lib/redis/client.rb', line 143 def pipelined(exception: true) super rescue ::RedisClient::Error => error raise if Client.resp3_unsupported?(error) Client.translate_error!(error) end |
#port ⇒ Object
94 95 96 |
# File 'lib/redis/client.rb', line 94 def port config.port unless config.path end |
#protocol ⇒ Object
86 87 88 |
# File 'lib/redis/client.rb', line 86 def protocol config.protocol end |
#server_url ⇒ Object
74 75 76 |
# File 'lib/redis/client.rb', line 74 def server_url config.server_url end |
#timeout ⇒ Object
78 79 80 |
# File 'lib/redis/client.rb', line 78 def timeout config.read_timeout end |
#username ⇒ Object
102 103 104 |
# File 'lib/redis/client.rb', line 102 def username config.username end |