redis-client 0.9.0 → 0.10.0
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 +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -5
- data/Rakefile +10 -5
- data/lib/redis_client/config.rb +13 -2
- data/lib/redis_client/middlewares.rb +9 -2
- data/lib/redis_client/ruby_connection/resp3.rb +8 -4
- data/lib/redis_client/version.rb +1 -1
- data/lib/redis_client.rb +14 -13
- 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: 27142ef61a44133a72e2a087afc39986ebcfe5fae30a7ee5f6eb3f702ef35ad2
|
4
|
+
data.tar.gz: f078880a52dec2f62d3b68188cfea8108ec433742f2f7e697def7a7bece332ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76c7b23cb0ba419fdb9505e5cd4eb58c1c6d38d2e2fcd82778429b346dfa02a94ce4a9077c28252d8c71d1667cc45270bfc0790190e42b0d37341493bbb105f5
|
7
|
+
data.tar.gz: 071ec50fabaa72512101d0f408154e432e5f9950927607d8d6bcf8c7f3d5d4c9f49f40de3a24aa6957019751a598b70ae9db525002c03d7beb05312fc082e053
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 0.10.0
|
4
|
+
|
5
|
+
- Added instance scoped middlewares. See: #53
|
6
|
+
- Allow subclasses of accepted types as command arguments. Fix: #51
|
7
|
+
- Improve hiredis driver error messages.
|
8
|
+
|
3
9
|
# 0.9.0
|
4
10
|
|
5
11
|
- Automatically reconnect if the process was forked.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -343,12 +343,13 @@ end
|
|
343
343
|
|
344
344
|
## Production
|
345
345
|
|
346
|
-
### Instrumentation
|
346
|
+
### Instrumentation and Middlewares
|
347
347
|
|
348
|
-
`redis-client` offers a public
|
348
|
+
`redis-client` offers a public middleware API to aid in monitoring and library extension. Middleware can be registered
|
349
|
+
either globally or on a given configuration instance.
|
349
350
|
|
350
351
|
```ruby
|
351
|
-
module
|
352
|
+
module MyGlobalRedisInstrumentation
|
352
353
|
def connect(redis_config)
|
353
354
|
MyMonitoringService.instrument("redis.connect") { super }
|
354
355
|
end
|
@@ -361,10 +362,17 @@ module MyRedisInstrumentation
|
|
361
362
|
MyMonitoringService.instrument("redis.pipeline") { super }
|
362
363
|
end
|
363
364
|
end
|
364
|
-
RedisClient.register(
|
365
|
+
RedisClient.register(MyGlobalRedisInstrumentation)
|
365
366
|
```
|
366
367
|
|
367
|
-
Note that
|
368
|
+
Note that `RedisClient.register` is global and apply to all `RedisClient` instances.
|
369
|
+
|
370
|
+
To add middlewares to only a single client, you can provide them when creating the config:
|
371
|
+
|
372
|
+
```ruby
|
373
|
+
redis_config = RedisClient.config(middlewares: [AnotherRedisInstrumentation])
|
374
|
+
redis_config.new_client
|
375
|
+
```
|
368
376
|
|
369
377
|
### Timeouts
|
370
378
|
|
data/Rakefile
CHANGED
@@ -67,12 +67,15 @@ namespace :hiredis do
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
benchmark_suites = %w(single pipelined)
|
71
|
+
benchmark_modes = %i[ruby yjit hiredis]
|
70
72
|
namespace :benchmark do
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
output_path = "benchmark/#{
|
73
|
+
benchmark_suites.each do |suite|
|
74
|
+
benchmark_modes.each do |mode|
|
75
|
+
name = "#{suite}_#{mode}"
|
76
|
+
task name do
|
77
|
+
output_path = "benchmark/#{name}.md"
|
78
|
+
sh "rm", "-f", output_path
|
76
79
|
File.open(output_path, "w+") do |output|
|
77
80
|
output.puts("ruby: `#{RUBY_DESCRIPTION}`\n\n")
|
78
81
|
output.puts("redis-server: `#{`redis-server -v`.strip}`\n\n")
|
@@ -103,6 +106,8 @@ namespace :benchmark do
|
|
103
106
|
end
|
104
107
|
end
|
105
108
|
end
|
109
|
+
|
110
|
+
task all: benchmark_suites.flat_map { |s| benchmark_modes.flat_map { |m| "#{s}_#{m}" } }
|
106
111
|
end
|
107
112
|
|
108
113
|
if hiredis_supported
|
data/lib/redis_client/config.rb
CHANGED
@@ -13,7 +13,8 @@ class RedisClient
|
|
13
13
|
|
14
14
|
module Common
|
15
15
|
attr_reader :db, :password, :id, :ssl, :ssl_params, :command_builder, :inherit_socket,
|
16
|
-
:connect_timeout, :read_timeout, :write_timeout, :driver, :connection_prelude, :protocol
|
16
|
+
:connect_timeout, :read_timeout, :write_timeout, :driver, :connection_prelude, :protocol,
|
17
|
+
:middlewares_stack
|
17
18
|
|
18
19
|
alias_method :ssl?, :ssl
|
19
20
|
|
@@ -33,7 +34,8 @@ class RedisClient
|
|
33
34
|
client_implementation: RedisClient,
|
34
35
|
command_builder: CommandBuilder,
|
35
36
|
inherit_socket: false,
|
36
|
-
reconnect_attempts: false
|
37
|
+
reconnect_attempts: false,
|
38
|
+
middlewares: false
|
37
39
|
)
|
38
40
|
@username = username
|
39
41
|
@password = password
|
@@ -60,6 +62,15 @@ class RedisClient
|
|
60
62
|
reconnect_attempts = Array.new(reconnect_attempts, 0).freeze if reconnect_attempts.is_a?(Integer)
|
61
63
|
@reconnect_attempts = reconnect_attempts
|
62
64
|
@connection_prelude = build_connection_prelude
|
65
|
+
|
66
|
+
middlewares_stack = Middlewares
|
67
|
+
if middlewares && !middlewares.empty?
|
68
|
+
middlewares_stack = Class.new(Middlewares)
|
69
|
+
middlewares.each do |mod|
|
70
|
+
middlewares_stack.include(mod)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@middlewares_stack = middlewares_stack
|
63
74
|
end
|
64
75
|
|
65
76
|
def username
|
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class RedisClient
|
4
|
-
|
5
|
-
|
4
|
+
class BasicMiddleware
|
5
|
+
attr_reader :client
|
6
|
+
|
7
|
+
def initialize(client)
|
8
|
+
@client = client
|
9
|
+
end
|
6
10
|
|
7
11
|
def connect(_config)
|
8
12
|
yield
|
@@ -13,4 +17,7 @@ class RedisClient
|
|
13
17
|
end
|
14
18
|
alias_method :call_pipelined, :call
|
15
19
|
end
|
20
|
+
|
21
|
+
class Middlewares < BasicMiddleware
|
22
|
+
end
|
16
23
|
end
|
@@ -10,12 +10,12 @@ class RedisClient
|
|
10
10
|
|
11
11
|
EOL = "\r\n".b.freeze
|
12
12
|
EOL_SIZE = EOL.bytesize
|
13
|
-
DUMP_TYPES = {
|
13
|
+
DUMP_TYPES = { # rubocop:disable Style/MutableConstant
|
14
14
|
String => :dump_string,
|
15
15
|
Symbol => :dump_symbol,
|
16
16
|
Integer => :dump_numeric,
|
17
17
|
Float => :dump_numeric,
|
18
|
-
}
|
18
|
+
}
|
19
19
|
PARSER_TYPES = {
|
20
20
|
'#' => :parse_boolean,
|
21
21
|
'$' => :parse_blob,
|
@@ -55,8 +55,12 @@ class RedisClient
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def dump_any(object, buffer)
|
58
|
-
method = DUMP_TYPES.fetch(object.class) do
|
59
|
-
|
58
|
+
method = DUMP_TYPES.fetch(object.class) do |unexpected_class|
|
59
|
+
if superclass = DUMP_TYPES.keys.find { |t| t > unexpected_class }
|
60
|
+
DUMP_TYPES[unexpected_class] = DUMP_TYPES[superclass]
|
61
|
+
else
|
62
|
+
raise TypeError, "Unsupported command argument type: #{unexpected_class}"
|
63
|
+
end
|
60
64
|
end
|
61
65
|
send(method, object, buffer)
|
62
66
|
end
|
data/lib/redis_client/version.rb
CHANGED
data/lib/redis_client.rb
CHANGED
@@ -145,7 +145,7 @@ class RedisClient
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def register(middleware)
|
148
|
-
Middlewares.
|
148
|
+
Middlewares.include(middleware)
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
@@ -153,6 +153,7 @@ class RedisClient
|
|
153
153
|
|
154
154
|
def initialize(config, **)
|
155
155
|
super
|
156
|
+
@middlewares = config.middlewares_stack.new(self)
|
156
157
|
@raw_connection = nil
|
157
158
|
@disable_reconnection = false
|
158
159
|
end
|
@@ -195,7 +196,7 @@ class RedisClient
|
|
195
196
|
def call(*command, **kwargs)
|
196
197
|
command = @command_builder.generate(command, kwargs)
|
197
198
|
result = ensure_connected do |connection|
|
198
|
-
|
199
|
+
@middlewares.call(command, config) do
|
199
200
|
connection.call(command, nil)
|
200
201
|
end
|
201
202
|
end
|
@@ -210,7 +211,7 @@ class RedisClient
|
|
210
211
|
def call_v(command)
|
211
212
|
command = @command_builder.generate(command)
|
212
213
|
result = ensure_connected do |connection|
|
213
|
-
|
214
|
+
@middlewares.call(command, config) do
|
214
215
|
connection.call(command, nil)
|
215
216
|
end
|
216
217
|
end
|
@@ -225,7 +226,7 @@ class RedisClient
|
|
225
226
|
def call_once(*command, **kwargs)
|
226
227
|
command = @command_builder.generate(command, kwargs)
|
227
228
|
result = ensure_connected(retryable: false) do |connection|
|
228
|
-
|
229
|
+
@middlewares.call(command, config) do
|
229
230
|
connection.call(command, nil)
|
230
231
|
end
|
231
232
|
end
|
@@ -240,7 +241,7 @@ class RedisClient
|
|
240
241
|
def call_once_v(command)
|
241
242
|
command = @command_builder.generate(command)
|
242
243
|
result = ensure_connected(retryable: false) do |connection|
|
243
|
-
|
244
|
+
@middlewares.call(command, config) do
|
244
245
|
connection.call(command, nil)
|
245
246
|
end
|
246
247
|
end
|
@@ -256,7 +257,7 @@ class RedisClient
|
|
256
257
|
command = @command_builder.generate(command, kwargs)
|
257
258
|
error = nil
|
258
259
|
result = ensure_connected do |connection|
|
259
|
-
|
260
|
+
@middlewares.call(command, config) do
|
260
261
|
connection.call(command, timeout)
|
261
262
|
end
|
262
263
|
rescue ReadTimeoutError => error
|
@@ -276,7 +277,7 @@ class RedisClient
|
|
276
277
|
command = @command_builder.generate(command)
|
277
278
|
error = nil
|
278
279
|
result = ensure_connected do |connection|
|
279
|
-
|
280
|
+
@middlewares.call(command, config) do
|
280
281
|
connection.call(command, timeout)
|
281
282
|
end
|
282
283
|
rescue ReadTimeoutError => error
|
@@ -347,7 +348,7 @@ class RedisClient
|
|
347
348
|
else
|
348
349
|
results = ensure_connected(retryable: pipeline._retryable?) do |connection|
|
349
350
|
commands = pipeline._commands
|
350
|
-
|
351
|
+
@middlewares.call_pipelined(commands, config) do
|
351
352
|
connection.call_pipelined(commands, pipeline._timeouts)
|
352
353
|
end
|
353
354
|
end
|
@@ -367,7 +368,7 @@ class RedisClient
|
|
367
368
|
begin
|
368
369
|
if transaction = build_transaction(&block)
|
369
370
|
commands = transaction._commands
|
370
|
-
results =
|
371
|
+
results = @middlewares.call_pipelined(commands, config) do
|
371
372
|
connection.call_pipelined(commands, nil)
|
372
373
|
end.last
|
373
374
|
else
|
@@ -386,7 +387,7 @@ class RedisClient
|
|
386
387
|
else
|
387
388
|
ensure_connected(retryable: transaction._retryable?) do |connection|
|
388
389
|
commands = transaction._commands
|
389
|
-
|
390
|
+
@middlewares.call_pipelined(commands, config) do
|
390
391
|
connection.call_pipelined(commands, nil)
|
391
392
|
end.last
|
392
393
|
end
|
@@ -649,7 +650,7 @@ class RedisClient
|
|
649
650
|
def connect
|
650
651
|
@pid = Process.pid
|
651
652
|
|
652
|
-
connection =
|
653
|
+
connection = @middlewares.connect(config) do
|
653
654
|
config.driver.new(
|
654
655
|
config,
|
655
656
|
connect_timeout: connect_timeout,
|
@@ -667,13 +668,13 @@ class RedisClient
|
|
667
668
|
# The connection prelude is deliberately not sent to Middlewares
|
668
669
|
if config.sentinel?
|
669
670
|
prelude << ["ROLE"]
|
670
|
-
role, =
|
671
|
+
role, = @middlewares.call_pipelined(prelude, config) do
|
671
672
|
connection.call_pipelined(prelude, nil).last
|
672
673
|
end
|
673
674
|
config.check_role!(role)
|
674
675
|
else
|
675
676
|
unless prelude.empty?
|
676
|
-
|
677
|
+
@middlewares.call_pipelined(prelude, config) do
|
677
678
|
connection.call_pipelined(prelude, nil)
|
678
679
|
end
|
679
680
|
end
|
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.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: connection_pool
|