redis-cluster-client 0.3.5 → 0.3.7
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/lib/redis_client/cluster/command.rb +3 -6
- data/lib/redis_client/cluster/node/latency_replica.rb +4 -8
- data/lib/redis_client/cluster/node.rb +4 -4
- data/lib/redis_client/cluster/normalized_cmd_name.rb +1 -0
- data/lib/redis_client/cluster/pipeline.rb +169 -31
- data/lib/redis_client/cluster/router.rb +18 -18
- data/lib/redis_client/cluster.rb +1 -1
- data/lib/redis_client/cluster_config.rb +1 -1
- 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: 5243f77ab4cb1322ddaaade9b001780e8f24d702d293f56870ce9e1109780222
|
4
|
+
data.tar.gz: fabae20f3a0d9bede270602adb247ca3cbe2b36ad42d68ecdd908320b18a31bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 999a6b334092b0e498d5e8ba773131542d212d8e5b8cb7b117811c465ccb4385b5bea11637cd8e4febdebc3d1e33c218b084e13bd5e5f1686ab477dca0f9411f
|
7
|
+
data.tar.gz: b7edede3965d1878459a128a3e7cc0f5c84b9b3e434ec44c86b408830670058b28ec023ffeeb2f0bcd1503ba5c274c46ecf791f5b03ebbdcccff09c3e3b1cf06
|
@@ -10,7 +10,7 @@ class RedisClient
|
|
10
10
|
EMPTY_STRING = ''
|
11
11
|
|
12
12
|
class << self
|
13
|
-
def load(nodes)
|
13
|
+
def load(nodes)
|
14
14
|
errors = []
|
15
15
|
cmd = nil
|
16
16
|
nodes&.each do |node|
|
@@ -32,10 +32,7 @@ class RedisClient
|
|
32
32
|
|
33
33
|
def parse_command_details(rows)
|
34
34
|
rows&.reject { |row| row[0].nil? }.to_h do |row|
|
35
|
-
[
|
36
|
-
::RedisClient::Cluster::NormalizedCmdName.instance.get_by_name(row[0]),
|
37
|
-
{ arity: row[1], flags: row[2], first: row[3], last: row[4], step: row[5] }
|
38
|
-
]
|
35
|
+
[row[0].downcase, { arity: row[1], flags: row[2], first: row[3], last: row[4], step: row[5] }]
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
@@ -85,7 +82,7 @@ class RedisClient
|
|
85
82
|
@details.fetch(name).fetch(key)
|
86
83
|
end
|
87
84
|
|
88
|
-
def determine_first_key_position(command) # rubocop:disable Metrics/CyclomaticComplexity
|
85
|
+
def determine_first_key_position(command) # rubocop:disable Metrics/CyclomaticComplexity
|
89
86
|
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_command(command)
|
90
87
|
when 'eval', 'evalsha', 'zinterstore', 'zunionstore' then 3
|
91
88
|
when 'object' then 2
|
@@ -34,14 +34,13 @@ class RedisClient
|
|
34
34
|
|
35
35
|
def any_replica_node_key(seed: nil)
|
36
36
|
random = seed.nil? ? Random : Random.new(seed)
|
37
|
-
@existed_replicas.sample(random: random)
|
37
|
+
@existed_replicas.sample(random: random)&.first
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
|
-
def measure_latencies(clients) # rubocop:disable Metrics/
|
43
|
-
|
44
|
-
clients.each_slice(::RedisClient::Cluster::Node::MAX_THREADS) do |chuncked_clients|
|
42
|
+
def measure_latencies(clients) # rubocop:disable Metrics/AbcSize
|
43
|
+
clients.each_slice(::RedisClient::Cluster::Node::MAX_THREADS).each_with_object({}) do |chuncked_clients, acc|
|
45
44
|
threads = chuncked_clients.map do |k, v|
|
46
45
|
Thread.new(k, v) do |node_key, client|
|
47
46
|
Thread.pass
|
@@ -63,12 +62,9 @@ class RedisClient
|
|
63
62
|
|
64
63
|
threads.each do |t|
|
65
64
|
t.join
|
66
|
-
|
67
|
-
latencies[t.thread_variable_get(:node_key)] = t.thread_variable_get(:latency)
|
65
|
+
acc[t.thread_variable_get(:node_key)] = t.thread_variable_get(:latency)
|
68
66
|
end
|
69
67
|
end
|
70
|
-
|
71
|
-
latencies
|
72
68
|
end
|
73
69
|
|
74
70
|
def select_replica_clients(replications, clients)
|
@@ -37,7 +37,7 @@ class RedisClient
|
|
37
37
|
end
|
38
38
|
|
39
39
|
class << self
|
40
|
-
def load_info(options, **kwargs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/
|
40
|
+
def load_info(options, **kwargs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
41
41
|
startup_size = options.size > MAX_STARTUP_SAMPLE ? MAX_STARTUP_SAMPLE : options.size
|
42
42
|
node_info_list = errors = nil
|
43
43
|
startup_options = options.to_a.sample(MAX_STARTUP_SAMPLE).to_h
|
@@ -83,7 +83,7 @@ class RedisClient
|
|
83
83
|
|
84
84
|
# @see https://redis.io/commands/cluster-nodes/
|
85
85
|
# @see https://github.com/redis/redis/blob/78960ad57b8a5e6af743d789ed8fd767e37d42b8/src/cluster.c#L4660-L4683
|
86
|
-
def parse_node_info(info) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
86
|
+
def parse_node_info(info) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
87
87
|
rows = info.split("\n").map(&:split)
|
88
88
|
rows.each { |arr| arr[2] = arr[2].split(',') }
|
89
89
|
rows.select! { |arr| arr[7] == 'connected' && (arr[2] & %w[fail? fail handshake noaddr noflags]).empty? }
|
@@ -232,7 +232,7 @@ class RedisClient
|
|
232
232
|
client.send(method, *args, command, &block)
|
233
233
|
end
|
234
234
|
|
235
|
-
[results
|
235
|
+
[results&.values, errors]
|
236
236
|
end
|
237
237
|
|
238
238
|
def call_multiple_nodes!(clients, method, command, args, &block)
|
@@ -242,7 +242,7 @@ class RedisClient
|
|
242
242
|
raise ::RedisClient::Cluster::ErrorCollection, errors
|
243
243
|
end
|
244
244
|
|
245
|
-
def try_map(clients) # rubocop:disable Metrics/
|
245
|
+
def try_map(clients) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
246
246
|
results = errors = nil
|
247
247
|
clients.each_slice(MAX_THREADS) do |chuncked_clients|
|
248
248
|
threads = chuncked_clients.map do |k, v|
|
@@ -2,84 +2,172 @@
|
|
2
2
|
|
3
3
|
require 'redis_client'
|
4
4
|
require 'redis_client/cluster/errors'
|
5
|
+
require 'redis_client/connection_mixin'
|
6
|
+
require 'redis_client/middlewares'
|
7
|
+
require 'redis_client/pooled'
|
5
8
|
|
6
9
|
class RedisClient
|
7
10
|
class Cluster
|
8
11
|
class Pipeline
|
12
|
+
class Extended < ::RedisClient::Pipeline
|
13
|
+
attr_reader :outer_indices
|
14
|
+
|
15
|
+
def initialize(command_builder)
|
16
|
+
super
|
17
|
+
@outer_indices = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_outer_index(index)
|
21
|
+
@outer_indices ||= []
|
22
|
+
@outer_indices << index
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_inner_index(outer_index)
|
26
|
+
@outer_indices&.find_index(outer_index)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_callee_method(inner_index)
|
30
|
+
if @timeouts.is_a?(Array) && !@timeouts[inner_index].nil?
|
31
|
+
:blocking_call_v
|
32
|
+
elsif _retryable?
|
33
|
+
:call_once_v
|
34
|
+
else
|
35
|
+
:call_v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_command(inner_index)
|
40
|
+
@commands.is_a?(Array) ? @commands[inner_index] : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_timeout(inner_index)
|
44
|
+
@timeouts.is_a?(Array) ? @timeouts[inner_index] : nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_block(inner_index)
|
48
|
+
@blocks.is_a?(Array) ? @blocks[inner_index] : nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
::RedisClient::ConnectionMixin.module_eval do
|
53
|
+
def call_pipelined_aware_of_redirection(commands, timeouts) # rubocop:disable Metrics/AbcSize
|
54
|
+
size = commands.size
|
55
|
+
results = Array.new(commands.size)
|
56
|
+
@pending_reads += size
|
57
|
+
write_multi(commands)
|
58
|
+
|
59
|
+
redirection_indices = nil
|
60
|
+
size.times do |index|
|
61
|
+
timeout = timeouts && timeouts[index]
|
62
|
+
result = read(timeout)
|
63
|
+
@pending_reads -= 1
|
64
|
+
if result.is_a?(CommandError)
|
65
|
+
result._set_command(commands[index])
|
66
|
+
if result.message.start_with?('MOVED', 'ASK')
|
67
|
+
redirection_indices ||= []
|
68
|
+
redirection_indices << index
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
results[index] = result
|
73
|
+
end
|
74
|
+
|
75
|
+
return results if redirection_indices.nil?
|
76
|
+
|
77
|
+
err = ::RedisClient::Cluster::Pipeline::RedirectionNeeded.new
|
78
|
+
err.replies = results
|
79
|
+
err.indices = redirection_indices
|
80
|
+
raise err
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
9
84
|
ReplySizeError = Class.new(::RedisClient::Error)
|
85
|
+
|
86
|
+
class RedirectionNeeded < ::RedisClient::Error
|
87
|
+
attr_accessor :replies, :indices
|
88
|
+
end
|
89
|
+
|
10
90
|
MAX_THREADS = Integer(ENV.fetch('REDIS_CLIENT_MAX_THREADS', 5))
|
11
91
|
|
12
92
|
def initialize(router, command_builder, seed: Random.new_seed)
|
13
93
|
@router = router
|
14
94
|
@command_builder = command_builder
|
15
|
-
@grouped = {}
|
16
|
-
@size = 0
|
17
95
|
@seed = seed
|
96
|
+
@pipelines = nil
|
97
|
+
@size = 0
|
18
98
|
end
|
19
99
|
|
20
100
|
def call(*args, **kwargs, &block)
|
21
101
|
command = @command_builder.generate(args, kwargs)
|
22
102
|
node_key = @router.find_node_key(command, seed: @seed)
|
23
|
-
|
103
|
+
append_pipeline(node_key).call_v(command, &block)
|
24
104
|
end
|
25
105
|
|
26
106
|
def call_v(args, &block)
|
27
107
|
command = @command_builder.generate(args)
|
28
108
|
node_key = @router.find_node_key(command, seed: @seed)
|
29
|
-
|
109
|
+
append_pipeline(node_key).call_v(command, &block)
|
30
110
|
end
|
31
111
|
|
32
112
|
def call_once(*args, **kwargs, &block)
|
33
113
|
command = @command_builder.generate(args, kwargs)
|
34
114
|
node_key = @router.find_node_key(command, seed: @seed)
|
35
|
-
|
115
|
+
append_pipeline(node_key).call_once_v(command, &block)
|
36
116
|
end
|
37
117
|
|
38
118
|
def call_once_v(args, &block)
|
39
119
|
command = @command_builder.generate(args)
|
40
120
|
node_key = @router.find_node_key(command, seed: @seed)
|
41
|
-
|
121
|
+
append_pipeline(node_key).call_once_v(command, &block)
|
42
122
|
end
|
43
123
|
|
44
124
|
def blocking_call(timeout, *args, **kwargs, &block)
|
45
125
|
command = @command_builder.generate(args, kwargs)
|
46
126
|
node_key = @router.find_node_key(command, seed: @seed)
|
47
|
-
|
127
|
+
append_pipeline(node_key).blocking_call_v(timeout, command, &block)
|
48
128
|
end
|
49
129
|
|
50
130
|
def blocking_call_v(timeout, args, &block)
|
51
131
|
command = @command_builder.generate(args)
|
52
132
|
node_key = @router.find_node_key(command, seed: @seed)
|
53
|
-
|
133
|
+
append_pipeline(node_key).blocking_call_v(timeout, command, &block)
|
54
134
|
end
|
55
135
|
|
56
136
|
def empty?
|
57
137
|
@size.zero?
|
58
138
|
end
|
59
139
|
|
60
|
-
#
|
61
|
-
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
140
|
+
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
62
141
|
all_replies = errors = nil
|
63
|
-
@
|
64
|
-
threads =
|
65
|
-
Thread.new(
|
142
|
+
@pipelines&.each_slice(MAX_THREADS) do |chuncked_pipelines|
|
143
|
+
threads = chuncked_pipelines.map do |node_key, pipeline|
|
144
|
+
Thread.new(node_key, pipeline) do |nk, pl|
|
66
145
|
Thread.pass
|
67
|
-
|
68
|
-
|
146
|
+
Thread.current.thread_variable_set(:node_key, nk)
|
147
|
+
replies = do_pipelining(@router.find_node(nk), pl)
|
148
|
+
raise ReplySizeError, "commands: #{pl._size}, replies: #{replies.size}" if pl._size != replies.size
|
69
149
|
|
70
|
-
Thread.current.thread_variable_set(:rows, rows)
|
71
150
|
Thread.current.thread_variable_set(:replies, replies)
|
151
|
+
rescue ::RedisClient::Cluster::Pipeline::RedirectionNeeded => e
|
152
|
+
Thread.current.thread_variable_set(:redirection_needed, e)
|
72
153
|
rescue StandardError => e
|
73
|
-
Thread.current.thread_variable_set(:node_key, node_key)
|
74
154
|
Thread.current.thread_variable_set(:error, e)
|
75
155
|
end
|
76
156
|
end
|
77
157
|
|
158
|
+
threads.each(&:join)
|
78
159
|
threads.each do |t|
|
79
|
-
t.join
|
80
160
|
if t.thread_variable?(:replies)
|
81
161
|
all_replies ||= Array.new(@size)
|
82
|
-
|
162
|
+
@pipelines[t.thread_variable_get(:node_key)]
|
163
|
+
.outer_indices
|
164
|
+
.each_with_index { |outer, inner| all_replies[outer] = t.thread_variable_get(:replies)[inner] }
|
165
|
+
elsif t.thread_variable?(:redirection_needed)
|
166
|
+
all_replies ||= Array.new(@size)
|
167
|
+
pipeline = @pipelines[t.thread_variable_get(:node_key)]
|
168
|
+
err = t.thread_variable_get(:redirection_needed)
|
169
|
+
err.indices.each { |i| err.replies[i] = handle_redirection(err.replies[i], pipeline, i) }
|
170
|
+
pipeline.outer_indices.each_with_index { |outer, inner| all_replies[outer] = err.replies[inner] }
|
83
171
|
elsif t.thread_variable?(:error)
|
84
172
|
errors ||= {}
|
85
173
|
errors[t.thread_variable_get(:node_key)] = t.thread_variable_get(:error)
|
@@ -87,28 +175,78 @@ class RedisClient
|
|
87
175
|
end
|
88
176
|
end
|
89
177
|
|
90
|
-
|
178
|
+
raise ::RedisClient::Cluster::ErrorCollection, errors unless errors.nil?
|
91
179
|
|
92
|
-
|
180
|
+
all_replies
|
93
181
|
end
|
94
182
|
|
95
183
|
private
|
96
184
|
|
97
|
-
def
|
98
|
-
@
|
99
|
-
@
|
185
|
+
def append_pipeline(node_key)
|
186
|
+
@pipelines ||= {}
|
187
|
+
@pipelines[node_key] ||= ::RedisClient::Cluster::Pipeline::Extended.new(@command_builder)
|
188
|
+
@pipelines[node_key].add_outer_index(@size)
|
100
189
|
@size += 1
|
190
|
+
@pipelines[node_key]
|
101
191
|
end
|
102
192
|
|
103
|
-
def do_pipelining(
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
193
|
+
def do_pipelining(client, pipeline)
|
194
|
+
case client
|
195
|
+
when ::RedisClient then send_pipeline(client, pipeline)
|
196
|
+
when ::RedisClient::Pooled then client.with { |cli| send_pipeline(cli, pipeline) }
|
197
|
+
else raise NotImplementedError, "#{client.class.name}#pipelined for cluster client"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def send_pipeline(client, pipeline)
|
202
|
+
results = client.send(:ensure_connected, retryable: pipeline._retryable?) do |connection|
|
203
|
+
commands = pipeline._commands
|
204
|
+
::RedisClient::Middlewares.call_pipelined(commands, client.config) do
|
205
|
+
connection.call_pipelined_aware_of_redirection(commands, pipeline._timeouts)
|
110
206
|
end
|
111
207
|
end
|
208
|
+
|
209
|
+
pipeline._coerce!(results)
|
210
|
+
end
|
211
|
+
|
212
|
+
def handle_redirection(err, pipeline, inner_index)
|
213
|
+
return err unless err.is_a?(::RedisClient::CommandError)
|
214
|
+
|
215
|
+
if err.message.start_with?('MOVED')
|
216
|
+
node = @router.assign_redirection_node(err.message)
|
217
|
+
try_redirection(node, pipeline, inner_index)
|
218
|
+
elsif err.message.start_with?('ASK')
|
219
|
+
node = @router.assign_asking_node(err.message)
|
220
|
+
try_asking(node) ? try_redirection(node, pipeline, inner_index) : err
|
221
|
+
else
|
222
|
+
err
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def try_redirection(node, pipeline, inner_index)
|
227
|
+
redirect_command(node, pipeline, inner_index)
|
228
|
+
rescue StandardError => e
|
229
|
+
e
|
230
|
+
end
|
231
|
+
|
232
|
+
def redirect_command(node, pipeline, inner_index)
|
233
|
+
method = pipeline.get_callee_method(inner_index)
|
234
|
+
command = pipeline.get_command(inner_index)
|
235
|
+
timeout = pipeline.get_timeout(inner_index)
|
236
|
+
block = pipeline.get_block(inner_index)
|
237
|
+
args = timeout.nil? ? [] : [timeout]
|
238
|
+
|
239
|
+
if block.nil?
|
240
|
+
@router.try_send(node, method, command, args)
|
241
|
+
else
|
242
|
+
@router.try_send(node, method, command, args, &block)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def try_asking(node)
|
247
|
+
node.call('ASKING') == 'OK'
|
248
|
+
rescue StandardError
|
249
|
+
false
|
112
250
|
end
|
113
251
|
end
|
114
252
|
end
|
@@ -25,7 +25,7 @@ class RedisClient
|
|
25
25
|
@command_builder = @config.command_builder
|
26
26
|
end
|
27
27
|
|
28
|
-
def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/
|
28
|
+
def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
29
29
|
cmd = ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_command(command)
|
30
30
|
case cmd
|
31
31
|
when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
|
@@ -65,7 +65,7 @@ class RedisClient
|
|
65
65
|
|
66
66
|
# @see https://redis.io/topics/cluster-spec#redirection-and-resharding
|
67
67
|
# Redirection and resharding
|
68
|
-
def try_send(node, method, command, args, retry_count: 3, &block) # rubocop:disable Metrics/
|
68
|
+
def try_send(node, method, command, args, retry_count: 3, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
69
69
|
if args.empty?
|
70
70
|
# prevent memory allocation for variable-length args
|
71
71
|
node.send(method, command, &block)
|
@@ -100,7 +100,7 @@ class RedisClient
|
|
100
100
|
retry
|
101
101
|
end
|
102
102
|
|
103
|
-
def try_delegate(node, method, *args, retry_count: 3, **kwargs, &block) # rubocop:disable Metrics/
|
103
|
+
def try_delegate(node, method, *args, retry_count: 3, **kwargs, &block) # rubocop:disable Metrics/AbcSize
|
104
104
|
node.send(method, *args, **kwargs, &block)
|
105
105
|
rescue ::RedisClient::CommandError => e
|
106
106
|
raise if retry_count <= 0
|
@@ -129,7 +129,7 @@ class RedisClient
|
|
129
129
|
retry
|
130
130
|
end
|
131
131
|
|
132
|
-
def scan(*command, seed: nil, **kwargs) # rubocop:disable Metrics/
|
132
|
+
def scan(*command, seed: nil, **kwargs) # rubocop:disable Metrics/AbcSize
|
133
133
|
command = @command_builder.generate(command, kwargs)
|
134
134
|
|
135
135
|
command[1] = ZERO_CURSOR_FOR_SCAN if command.size == 1
|
@@ -172,7 +172,7 @@ class RedisClient
|
|
172
172
|
def find_node(node_key, retry_count: 3)
|
173
173
|
@node.find_by(node_key)
|
174
174
|
rescue ::RedisClient::Cluster::Node::ReloadNeeded
|
175
|
-
raise ::
|
175
|
+
raise ::RedisClient::Cluster::NodeMightBeDown if retry_count <= 0
|
176
176
|
|
177
177
|
update_cluster_info!
|
178
178
|
retry_count -= 1
|
@@ -183,6 +183,18 @@ class RedisClient
|
|
183
183
|
@command.exists?(name)
|
184
184
|
end
|
185
185
|
|
186
|
+
def assign_redirection_node(err_msg)
|
187
|
+
_, slot, node_key = err_msg.split
|
188
|
+
slot = slot.to_i
|
189
|
+
@node.update_slot(slot, node_key)
|
190
|
+
find_node(node_key)
|
191
|
+
end
|
192
|
+
|
193
|
+
def assign_asking_node(err_msg)
|
194
|
+
_, _, node_key = err_msg.split
|
195
|
+
find_node(node_key)
|
196
|
+
end
|
197
|
+
|
186
198
|
private
|
187
199
|
|
188
200
|
def send_wait_command(method, command, args, retry_count: 3, &block)
|
@@ -258,19 +270,7 @@ class RedisClient
|
|
258
270
|
end
|
259
271
|
end
|
260
272
|
|
261
|
-
def
|
262
|
-
_, slot, node_key = err_msg.split
|
263
|
-
slot = slot.to_i
|
264
|
-
@node.update_slot(slot, node_key)
|
265
|
-
find_node(node_key)
|
266
|
-
end
|
267
|
-
|
268
|
-
def assign_asking_node(err_msg)
|
269
|
-
_, _, node_key = err_msg.split
|
270
|
-
find_node(node_key)
|
271
|
-
end
|
272
|
-
|
273
|
-
def fetch_cluster_info(config, pool: nil, **kwargs) # rubocop:disable Metrics/MethodLength
|
273
|
+
def fetch_cluster_info(config, pool: nil, **kwargs)
|
274
274
|
node_info = ::RedisClient::Cluster::Node.load_info(config.per_node_key, **kwargs)
|
275
275
|
node_addrs = node_info.map { |info| ::RedisClient::Cluster::NodeKey.hashify(info[:node_key]) }
|
276
276
|
config.update_node(node_addrs)
|
data/lib/redis_client/cluster.rb
CHANGED
@@ -81,7 +81,7 @@ class RedisClient
|
|
81
81
|
seed = @config.use_replica? && @config.replica_affinity == :random ? nil : Random.new_seed
|
82
82
|
pipeline = ::RedisClient::Cluster::Pipeline.new(@router, @command_builder, seed: seed)
|
83
83
|
yield pipeline
|
84
|
-
return [] if pipeline.empty?
|
84
|
+
return [] if pipeline.empty?
|
85
85
|
|
86
86
|
pipeline.execute
|
87
87
|
end
|
@@ -114,7 +114,7 @@ class RedisClient
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
def parse_node_url(addr) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
117
|
+
def parse_node_url(addr) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
118
118
|
return if addr.empty?
|
119
119
|
|
120
120
|
uri = URI(addr)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-cluster-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Taishi Kasuga
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|