redis-client 0.15.0 → 0.17.1
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 +4 -4
- data/CHANGELOG.md +16 -2
- data/Gemfile.lock +2 -2
- data/README.md +43 -8
- data/lib/redis_client/config.rb +5 -3
- data/lib/redis_client/ruby_connection/buffered_io.rb +0 -4
- data/lib/redis_client/ruby_connection/resp3.rb +2 -0
- data/lib/redis_client/ruby_connection.rb +0 -7
- data/lib/redis_client/sentinel_config.rb +18 -6
- data/lib/redis_client/version.rb +1 -1
- data/lib/redis_client.rb +7 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e73c2e13870d3adcb345e544fe99bbffa6ad1bf5f7267203e49f838c56a7492
|
4
|
+
data.tar.gz: d090544eb97a93ad0d21d5a6c14c40ffb3ca384425ccf27d82c797f0f7e2d35a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60e0fbf2c30888ac05855af2ba6b145ac96e0e011cc58d989f66e9379baa549c9af1ad2f7077ce431b334d6b1318b83463eac7bcb7a323752c79644e0dbce495
|
7
|
+
data.tar.gz: 1e3e10ef87472a412239261c0642e134f9521e83e49def834bb76b1aa6481c8e8fc9b13cfe1916c0f0ed43af8799a331e9649caa61155ce9eeb8391b0c15c98a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 0.17.1
|
4
|
+
|
5
|
+
- Add support for `NaN` in RESP3 protocol doubles.
|
6
|
+
This was initially missing from the spec and added about a year ago.
|
7
|
+
|
8
|
+
# 0.17.0
|
9
|
+
|
10
|
+
- Adds `sentinel_username` and `sentinel_password` options for `RedisClient#sentinel`
|
11
|
+
|
12
|
+
# 0.16.0
|
13
|
+
|
14
|
+
- Add `RedisClient#disable_reconnection`.
|
15
|
+
- Reverted the special discard of connection. A regular `close(2)` should be enough.
|
16
|
+
|
3
17
|
# 0.15.0
|
4
18
|
|
5
19
|
- Discard sockets rather than explictly close them when a fork is detected. #126.
|
@@ -66,7 +80,7 @@
|
|
66
80
|
|
67
81
|
- Make the client resilient to `Timeout.timeout` or `Thread#kill` use (it still is very much discouraged to use either).
|
68
82
|
Use of async interrupts could cause responses to be interleaved.
|
69
|
-
- hiredis: handle commands returning a top-level `false` (no command does this today, but some extensions might).
|
83
|
+
- hiredis: handle commands returning a top-level `false` (no command does this today, but some extensions might).
|
70
84
|
- Workaround a bug in Ruby 2.6 causing a crash if the `debug` gem is enabled when `redis-client` is being required. Fix: #48
|
71
85
|
|
72
86
|
# 0.8.0
|
@@ -85,7 +99,7 @@
|
|
85
99
|
|
86
100
|
- Raise a distinct `RedisClient::OutOfMemoryError`, for Redis `OOM` errors.
|
87
101
|
- Fix the instrumentation API to be called even for authentication commands.
|
88
|
-
- Fix `url:` configuration to accept a trailing slash.
|
102
|
+
- Fix `url:` configuration to accept a trailing slash.
|
89
103
|
|
90
104
|
# 0.7.1
|
91
105
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
redis-client (0.
|
4
|
+
redis-client (0.17.1)
|
5
5
|
connection_pool
|
6
6
|
|
7
7
|
GEM
|
@@ -19,7 +19,7 @@ GEM
|
|
19
19
|
ast (~> 2.4.1)
|
20
20
|
rainbow (3.1.1)
|
21
21
|
rake (13.0.6)
|
22
|
-
rake-compiler (1.2.
|
22
|
+
rake-compiler (1.2.5)
|
23
23
|
rake
|
24
24
|
redis (4.6.0)
|
25
25
|
regexp_parser (2.5.0)
|
data/README.md
CHANGED
@@ -42,7 +42,7 @@ redis.with do |r|
|
|
42
42
|
end
|
43
43
|
```
|
44
44
|
|
45
|
-
If you are working in a single
|
45
|
+
If you are working in a single-threaded environment, or wish to use your own connection pooling mechanism,
|
46
46
|
you can obtain a raw client with `#new_client`
|
47
47
|
|
48
48
|
```ruby
|
@@ -67,11 +67,11 @@ redis.call("GET", "mykey")
|
|
67
67
|
- `host`: The server hostname or IP address. Defaults to `"localhost"`.
|
68
68
|
- `port`: The server port. Defaults to `6379`.
|
69
69
|
- `path`: The path to a UNIX socket, if set `url`, `host` and `port` are ignored.
|
70
|
-
- `ssl`:
|
70
|
+
- `ssl`: Whether to connect using SSL or not.
|
71
71
|
- `ssl_params`: A configuration Hash passed to [`OpenSSL::SSL::SSLContext#set_params`](https://www.rubydoc.info/stdlib/openssl/OpenSSL%2FSSL%2FSSLContext:set_params), notable options include:
|
72
72
|
- `cert`: The path to the client certificate (e.g. `client.crt`).
|
73
73
|
- `key`: The path to the client key (e.g. `client.key`).
|
74
|
-
- `ca_file`: The certificate authority to use, useful for self
|
74
|
+
- `ca_file`: The certificate authority to use, useful for self-signed certificates (e.g. `ca.crt`),
|
75
75
|
- `db`: The database to select after connecting, defaults to `0`.
|
76
76
|
- `id` ID for the client connection, assigns name to current connection by sending `CLIENT SETNAME`.
|
77
77
|
- `username` Username to authenticate against server, defaults to `"default"`.
|
@@ -83,7 +83,7 @@ redis.call("GET", "mykey")
|
|
83
83
|
- `reconnect_attempts`: Specify how many times the client should retry to send queries. Defaults to `0`. Makes sure to read the [reconnection section](#reconnection) before enabling it.
|
84
84
|
- `circuit_breaker`: A Hash with circuit breaker configuration. Defaults to `nil`. See the [circuit breaker section](#circuit-breaker) for details.
|
85
85
|
- `protocol:` The version of the RESP protocol to use. Default to `3`.
|
86
|
-
- `custom`: A user
|
86
|
+
- `custom`: A user-owned value ignored by `redis-client` but available as `Config#custom`. This can be used to hold middleware configurations and other user-specific metadata.
|
87
87
|
|
88
88
|
### Sentinel support
|
89
89
|
|
@@ -128,6 +128,41 @@ but a few so that if one is down the client will try the next one. The client
|
|
128
128
|
is able to remember the last Sentinel that was able to reply correctly and will
|
129
129
|
use it for the next requests.
|
130
130
|
|
131
|
+
To [authenticate](https://redis.io/docs/management/sentinel/#configuring-sentinel-instances-with-authentication) Sentinel itself, you can specify the `sentinel_username` and `sentinel_password` options per instance. Exclude the `sentinel_username` option if you're using password-only authentication.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
SENTINELS = [{ host: '127.0.0.1', port: 26380},
|
135
|
+
{ host: '127.0.0.1', port: 26381}]
|
136
|
+
|
137
|
+
redis_config = RedisClient.sentinel(name: 'mymaster', sentinel_username: 'appuser', sentinel_password: 'mysecret', sentinels: SENTINELS, role: :master)
|
138
|
+
```
|
139
|
+
|
140
|
+
If you specify a username and/or password at the top level for your main Redis instance, Sentinel *will not* using thouse credentials
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# Use 'mysecret' to authenticate against the mymaster instance, but skip authentication for the sentinels:
|
144
|
+
SENTINELS = [{ host: '127.0.0.1', port: 26380 },
|
145
|
+
{ host: '127.0.0.1', port: 26381 }]
|
146
|
+
|
147
|
+
redis_config = RedisClient.sentinel(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret')
|
148
|
+
```
|
149
|
+
|
150
|
+
So you have to provide Sentinel credential and Redis explictly even they are the same
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
# Use 'mysecret' to authenticate against the mymaster instance and sentinel
|
154
|
+
SENTINELS = [{ host: '127.0.0.1', port: 26380 },
|
155
|
+
{ host: '127.0.0.1', port: 26381 }]
|
156
|
+
|
157
|
+
redis_config = RedisClient.sentinel(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret', sentinel_password: 'mysecret')
|
158
|
+
```
|
159
|
+
|
160
|
+
Also the `name`, `password`, `username` and `db` for Redis instance can be passed as an url:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
redis_config = RedisClient.sentinel(url: "redis://appuser:mysecret@mymaster/10", sentinels: SENTINELS, role: :master)
|
164
|
+
```
|
165
|
+
|
131
166
|
### Type support
|
132
167
|
|
133
168
|
Only a select few Ruby types are supported as arguments beside strings.
|
@@ -344,7 +379,7 @@ end
|
|
344
379
|
```
|
345
380
|
|
346
381
|
*Note*: pubsub connections are stateful, as such they won't ever reconnect automatically.
|
347
|
-
The caller is
|
382
|
+
The caller is responsible for reconnecting if the connection is lost and to resubscribe to
|
348
383
|
all channels.
|
349
384
|
|
350
385
|
## Production
|
@@ -380,7 +415,7 @@ redis_config = RedisClient.config(middlewares: [AnotherRedisInstrumentation])
|
|
380
415
|
redis_config.new_client
|
381
416
|
```
|
382
417
|
|
383
|
-
If middlewares need a client
|
418
|
+
If middlewares need a client-specific configuration, `Config#custom` can be used
|
384
419
|
|
385
420
|
```ruby
|
386
421
|
module MyGlobalRedisInstrumentation
|
@@ -454,9 +489,9 @@ redis_config = RedisClient.config(reconnect_attempts: [0, 0.05, 0.1])
|
|
454
489
|
```
|
455
490
|
|
456
491
|
This configuration is generally used when the Redis server is expected to failover or recover relatively quickly and
|
457
|
-
that it's not really
|
492
|
+
that it's not really possible to continue without issuing the command.
|
458
493
|
|
459
|
-
When the Redis server is used as an ephemeral cache, circuit breakers are generally
|
494
|
+
When the Redis server is used as an ephemeral cache, circuit breakers are generally preferred.
|
460
495
|
|
461
496
|
### Circuit Breaker
|
462
497
|
|
data/lib/redis_client/config.rb
CHANGED
@@ -159,21 +159,23 @@ class RedisClient
|
|
159
159
|
host: nil,
|
160
160
|
port: nil,
|
161
161
|
path: nil,
|
162
|
+
username: nil,
|
163
|
+
password: nil,
|
162
164
|
**kwargs
|
163
165
|
)
|
164
166
|
if url
|
165
167
|
url_config = URLConfig.new(url)
|
166
168
|
kwargs = {
|
167
169
|
ssl: url_config.ssl?,
|
168
|
-
username: url_config.username,
|
169
|
-
password: url_config.password,
|
170
170
|
db: url_config.db,
|
171
171
|
}.compact.merge(kwargs)
|
172
172
|
host ||= url_config.host
|
173
173
|
port ||= url_config.port
|
174
|
+
username ||= url_config.username
|
175
|
+
password ||= url_config.password
|
174
176
|
end
|
175
177
|
|
176
|
-
super(**kwargs)
|
178
|
+
super(username: username, password: password, **kwargs)
|
177
179
|
|
178
180
|
@host = host || DEFAULT_HOST
|
179
181
|
@port = Integer(port || DEFAULT_PORT)
|
@@ -9,8 +9,16 @@ class RedisClient
|
|
9
9
|
|
10
10
|
attr_reader :name
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
|
12
|
+
def initialize(
|
13
|
+
sentinels:,
|
14
|
+
sentinel_password: nil,
|
15
|
+
sentinel_username: nil,
|
16
|
+
role: :master,
|
17
|
+
name: nil,
|
18
|
+
url: nil,
|
19
|
+
**client_config
|
20
|
+
)
|
21
|
+
unless %i(master replica slave).include?(role.to_sym)
|
14
22
|
raise ArgumentError, "Expected role to be either :master or :replica, got: #{role.inspect}"
|
15
23
|
end
|
16
24
|
|
@@ -30,7 +38,11 @@ class RedisClient
|
|
30
38
|
end
|
31
39
|
|
32
40
|
@to_list_of_hash = @to_hash = nil
|
33
|
-
@extra_config = {
|
41
|
+
@extra_config = {
|
42
|
+
username: sentinel_username,
|
43
|
+
password: sentinel_password,
|
44
|
+
db: nil,
|
45
|
+
}
|
34
46
|
if client_config[:protocol] == 2
|
35
47
|
@extra_config[:protocol] = client_config[:protocol]
|
36
48
|
@to_list_of_hash = lambda do |may_be_a_list|
|
@@ -43,7 +55,7 @@ class RedisClient
|
|
43
55
|
end
|
44
56
|
|
45
57
|
@sentinels = {}.compare_by_identity
|
46
|
-
@role = role
|
58
|
+
@role = role.to_sym
|
47
59
|
@mutex = Mutex.new
|
48
60
|
@config = nil
|
49
61
|
|
@@ -106,9 +118,9 @@ class RedisClient
|
|
106
118
|
sentinels.map do |sentinel|
|
107
119
|
case sentinel
|
108
120
|
when String
|
109
|
-
Config.new(**@client_config, **@extra_config, url: sentinel
|
121
|
+
Config.new(**@client_config, **@extra_config, url: sentinel)
|
110
122
|
else
|
111
|
-
Config.new(**@client_config, **@extra_config, **sentinel
|
123
|
+
Config.new(**@client_config, **@extra_config, **sentinel)
|
112
124
|
end
|
113
125
|
end
|
114
126
|
end
|
data/lib/redis_client/version.rb
CHANGED
data/lib/redis_client.rb
CHANGED
@@ -175,6 +175,10 @@ class RedisClient
|
|
175
175
|
"#<#{self.class.name} #{config.server_url}#{id_string}>"
|
176
176
|
end
|
177
177
|
|
178
|
+
def server_url
|
179
|
+
config.server_url
|
180
|
+
end
|
181
|
+
|
178
182
|
def size
|
179
183
|
1
|
180
184
|
end
|
@@ -358,9 +362,8 @@ class RedisClient
|
|
358
362
|
self
|
359
363
|
end
|
360
364
|
|
361
|
-
def
|
362
|
-
|
363
|
-
self
|
365
|
+
def disable_reconnection(&block)
|
366
|
+
ensure_connected(retryable: false, &block)
|
364
367
|
end
|
365
368
|
|
366
369
|
def pipelined
|
@@ -623,7 +626,7 @@ class RedisClient
|
|
623
626
|
end
|
624
627
|
|
625
628
|
def ensure_connected(retryable: true)
|
626
|
-
|
629
|
+
close if !config.inherit_socket && @pid != PIDCache.pid
|
627
630
|
|
628
631
|
if @disable_reconnection
|
629
632
|
if block_given?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: connection_pool
|