redis-cluster-client 0.0.6 → 0.0.9
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 032431ff16773725b9cb68482bc5df78affdf23e66b6bbd91b6ddbabdd9da921
|
4
|
+
data.tar.gz: dc789f59f6509e35ab23df03a70867b5e8414ee3bb327462fbcd5d63be4c6744
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6013ff65d8dc06b776b7b201244d75eaf62993368f5285d823472f78bec2c81639734f23c32793bc1b8d1981905e5794e35e4e353696d70f1d66930434e6104f
|
7
|
+
data.tar.gz: 0e1dc5f17a9706c2fc64bdd03e74ee457f9b9aea81740cdeb5459bd9bbc769b6353047b64ef008b6d34b950fbc7cb8cf57e66c9deb41d33edbacaba78ca2a12e
|
@@ -68,12 +68,14 @@ class RedisClient
|
|
68
68
|
@details.fetch(name).fetch(key)
|
69
69
|
end
|
70
70
|
|
71
|
-
def determine_first_key_position(command) # rubocop:disable Metrics/CyclomaticComplexity
|
71
|
+
def determine_first_key_position(command) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
72
72
|
case command&.flatten&.first.to_s.downcase
|
73
|
-
when 'eval', 'evalsha', '
|
73
|
+
when 'eval', 'evalsha', 'zinterstore', 'zunionstore' then 3
|
74
74
|
when 'object' then 2
|
75
75
|
when 'memory'
|
76
76
|
command[1].to_s.casecmp('usage').zero? ? 2 : 0
|
77
|
+
when 'migrate'
|
78
|
+
command[3] == '""' ? determine_optional_key_position(command, 'keys') : 3
|
77
79
|
when 'xread', 'xreadgroup'
|
78
80
|
determine_optional_key_position(command, 'streams')
|
79
81
|
else
|
@@ -29,7 +29,7 @@ class RedisClient
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# Raised when error occurs on any node of cluster.
|
32
|
-
class
|
32
|
+
class ErrorCollection < ::RedisClient::Error
|
33
33
|
attr_reader :errors
|
34
34
|
|
35
35
|
def initialize(errors)
|
@@ -51,5 +51,15 @@ class RedisClient
|
|
51
51
|
super("Cluster client doesn't know which node the #{command} command should be sent to.")
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
class NodeMightBeDown < ::RedisClient::Error
|
56
|
+
def initialize(_ = '')
|
57
|
+
super(
|
58
|
+
'The client is trying to fetch the latest cluster state '\
|
59
|
+
'because a subset of nodes might be down. '\
|
60
|
+
'It might continue to raise errors for a while.'
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
54
64
|
end
|
55
65
|
end
|
@@ -12,6 +12,7 @@ class RedisClient
|
|
12
12
|
SLOT_SIZE = 16_384
|
13
13
|
MIN_SLOT = 0
|
14
14
|
MAX_SLOT = SLOT_SIZE - 1
|
15
|
+
MAX_STARTUP_SAMPLE = 37
|
15
16
|
IGNORE_GENERIC_CONFIG_KEYS = %i[url host port path].freeze
|
16
17
|
|
17
18
|
ReloadNeeded = Class.new(::RedisClient::Error)
|
@@ -32,19 +33,33 @@ class RedisClient
|
|
32
33
|
end
|
33
34
|
|
34
35
|
class << self
|
35
|
-
def load_info(options, **kwargs)
|
36
|
-
|
37
|
-
|
38
|
-
errors =
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
def load_info(options, **kwargs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
37
|
+
startup_size = options.size > MAX_STARTUP_SAMPLE ? MAX_STARTUP_SAMPLE : options.size
|
38
|
+
node_info_list = Array.new(startup_size)
|
39
|
+
errors = Array.new(startup_size)
|
40
|
+
startup_options = options.to_a.sample(MAX_STARTUP_SAMPLE).to_h
|
41
|
+
startup_nodes = ::RedisClient::Cluster::Node.new(startup_options, **kwargs)
|
42
|
+
threads = startup_nodes.each_with_index.map do |raw_client, idx|
|
43
|
+
Thread.new(raw_client, idx) do |cli, i|
|
44
|
+
Thread.pass
|
45
|
+
reply = cli.call('CLUSTER', 'NODES')
|
46
|
+
node_info_list[i] = parse_node_info(reply)
|
47
|
+
rescue StandardError => e
|
48
|
+
errors[i] = e
|
49
|
+
ensure
|
50
|
+
cli&.close
|
51
|
+
end
|
52
|
+
end
|
53
|
+
threads.each(&:join)
|
54
|
+
raise ::RedisClient::Cluster::InitialSetupError, errors if node_info_list.all?(&:nil?)
|
55
|
+
|
56
|
+
grouped = node_info_list.compact.group_by do |rows|
|
57
|
+
rows.sort_by { |row| row[:id] }
|
58
|
+
.map { |r| "#{r[:id]}#{r[:node_key]}#{r[:role]}#{r[:primary_id]}#{r[:config_epoch]}" }
|
59
|
+
.join
|
43
60
|
end
|
44
61
|
|
45
|
-
|
46
|
-
ensure
|
47
|
-
startup_nodes&.each(&:close)
|
62
|
+
grouped.max_by { |_, v| v.size }[1].first
|
48
63
|
end
|
49
64
|
|
50
65
|
private
|
@@ -109,32 +124,58 @@ class RedisClient
|
|
109
124
|
end
|
110
125
|
|
111
126
|
def find_by(node_key)
|
127
|
+
raise ReloadNeeded if node_key.nil? || !@clients.key?(node_key)
|
128
|
+
|
112
129
|
@clients.fetch(node_key)
|
113
|
-
rescue KeyError
|
114
|
-
raise ReloadNeeded
|
115
130
|
end
|
116
131
|
|
117
|
-
def call_all(method, *
|
118
|
-
try_map
|
132
|
+
def call_all(method, *args, **kwargs, &block)
|
133
|
+
results, errors = try_map do |_, client|
|
134
|
+
client.send(method, *args, **kwargs, &block)
|
135
|
+
end
|
136
|
+
|
137
|
+
return results.values if errors.empty?
|
138
|
+
|
139
|
+
raise ::RedisClient::Cluster::ErrorCollection, errors
|
119
140
|
end
|
120
141
|
|
121
|
-
def
|
122
|
-
try_map do |node_key, client|
|
142
|
+
def call_primaries(method, *args, **kwargs, &block)
|
143
|
+
results, errors = try_map do |node_key, client|
|
123
144
|
next if replica?(node_key)
|
124
145
|
|
125
|
-
client.send(method, *
|
126
|
-
end
|
146
|
+
client.send(method, *args, **kwargs, &block)
|
147
|
+
end
|
148
|
+
|
149
|
+
return results.values if errors.empty?
|
150
|
+
|
151
|
+
raise ::RedisClient::Cluster::ErrorCollection, errors
|
127
152
|
end
|
128
153
|
|
129
|
-
def
|
130
|
-
return
|
154
|
+
def call_replicas(method, *args, **kwargs, &block)
|
155
|
+
return call_primaries(method, *args, **kwargs, &block) if replica_disabled?
|
131
156
|
|
132
157
|
replica_node_keys = @replications.values.map(&:sample)
|
133
|
-
try_map do |node_key, client|
|
158
|
+
results, errors = try_map do |node_key, client|
|
134
159
|
next if primary?(node_key) || !replica_node_keys.include?(node_key)
|
135
160
|
|
136
|
-
client.send(method, *
|
137
|
-
end
|
161
|
+
client.send(method, *args, **kwargs, &block)
|
162
|
+
end
|
163
|
+
|
164
|
+
return results.values if errors.empty?
|
165
|
+
|
166
|
+
raise ::RedisClient::Cluster::ErrorCollection, errors
|
167
|
+
end
|
168
|
+
|
169
|
+
def send_ping(method, *args, **kwargs, &block)
|
170
|
+
results, errors = try_map do |_, client|
|
171
|
+
client.send(method, *args, **kwargs, &block)
|
172
|
+
end
|
173
|
+
|
174
|
+
return results.values if errors.empty?
|
175
|
+
|
176
|
+
raise ReloadNeeded if errors.values.any?(::RedisClient::ConnectionError)
|
177
|
+
|
178
|
+
raise ::RedisClient::Cluster::ErrorCollection, errors
|
138
179
|
end
|
139
180
|
|
140
181
|
def scale_reading_clients
|
@@ -144,14 +185,9 @@ class RedisClient
|
|
144
185
|
end
|
145
186
|
end
|
146
187
|
|
147
|
-
def slot_exists?(slot)
|
148
|
-
slot = Integer(slot)
|
149
|
-
return false if slot < MIN_SLOT || slot > MAX_SLOT
|
150
|
-
|
151
|
-
!@slots[slot].nil?
|
152
|
-
end
|
153
|
-
|
154
188
|
def find_node_key_of_primary(slot)
|
189
|
+
return if slot.nil?
|
190
|
+
|
155
191
|
slot = Integer(slot)
|
156
192
|
return if slot < MIN_SLOT || slot > MAX_SLOT
|
157
193
|
|
@@ -159,6 +195,8 @@ class RedisClient
|
|
159
195
|
end
|
160
196
|
|
161
197
|
def find_node_key_of_replica(slot)
|
198
|
+
return if slot.nil?
|
199
|
+
|
162
200
|
slot = Integer(slot)
|
163
201
|
return if slot < MIN_SLOT || slot > MAX_SLOT
|
164
202
|
|
@@ -228,22 +266,20 @@ class RedisClient
|
|
228
266
|
end
|
229
267
|
|
230
268
|
def try_map # rubocop:disable Metrics/MethodLength
|
231
|
-
errors = {}
|
232
269
|
results = {}
|
270
|
+
errors = {}
|
233
271
|
threads = @clients.map do |k, v|
|
234
272
|
Thread.new(k, v) do |node_key, client|
|
235
273
|
Thread.pass
|
236
274
|
reply = yield(node_key, client)
|
237
275
|
results[node_key] = reply unless reply.nil?
|
238
|
-
rescue
|
276
|
+
rescue StandardError => e
|
239
277
|
errors[node_key] = e
|
240
278
|
end
|
241
279
|
end
|
242
280
|
|
243
281
|
threads.each(&:join)
|
244
|
-
|
245
|
-
|
246
|
-
raise ::RedisClient::Cluster::CommandErrorCollection, errors
|
282
|
+
[results, errors]
|
247
283
|
end
|
248
284
|
end
|
249
285
|
end
|
data/lib/redis_client/cluster.rb
CHANGED
@@ -40,9 +40,10 @@ class RedisClient
|
|
40
40
|
@size.zero?
|
41
41
|
end
|
42
42
|
|
43
|
-
# TODO: https://github.com/redis-rb/redis-cluster-client/issues/37
|
44
|
-
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
43
|
+
# TODO: https://github.com/redis-rb/redis-cluster-client/issues/37 handle redirections
|
44
|
+
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
45
45
|
all_replies = Array.new(@size)
|
46
|
+
errors = {}
|
46
47
|
threads = @grouped.map do |k, v|
|
47
48
|
Thread.new(@client, k, v) do |client, node_key, rows|
|
48
49
|
Thread.pass
|
@@ -60,11 +61,15 @@ class RedisClient
|
|
60
61
|
raise ReplySizeError, "commands: #{rows.size}, replies: #{replies.size}" if rows.size != replies.size
|
61
62
|
|
62
63
|
rows.each_with_index { |row, idx| all_replies[row.first] = replies[idx] }
|
64
|
+
rescue StandardError => e
|
65
|
+
errors[node_key] = e
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
66
69
|
threads.each(&:join)
|
67
|
-
all_replies
|
70
|
+
return all_replies if errors.empty?
|
71
|
+
|
72
|
+
raise ::RedisClient::Cluster::ErrorCollection, errors
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
@@ -122,8 +127,7 @@ class RedisClient
|
|
122
127
|
end
|
123
128
|
|
124
129
|
def blocking_call(timeout, *command, **kwargs)
|
125
|
-
|
126
|
-
try_send(node, :blocking_call, timeout, *command, **kwargs)
|
130
|
+
send_command(:blocking_call, timeout, *command, **kwargs)
|
127
131
|
end
|
128
132
|
|
129
133
|
def scan(*args, **kwargs, &block)
|
@@ -165,8 +169,10 @@ class RedisClient
|
|
165
169
|
end
|
166
170
|
|
167
171
|
def close
|
168
|
-
@node.
|
172
|
+
@node.call_all(:close)
|
169
173
|
nil
|
174
|
+
rescue StandardError
|
175
|
+
# ignore
|
170
176
|
end
|
171
177
|
|
172
178
|
private
|
@@ -179,102 +185,124 @@ class RedisClient
|
|
179
185
|
node_info: node_info, pool: pool, with_replica: config.use_replica?, **kwargs)
|
180
186
|
end
|
181
187
|
|
182
|
-
def send_command(method, *
|
188
|
+
def send_command(method, *args, **kwargs, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
189
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
190
|
+
|
183
191
|
cmd = command.first.to_s.downcase
|
184
192
|
case cmd
|
185
|
-
when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
|
186
|
-
@node.call_all(method, *
|
193
|
+
when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
|
194
|
+
@node.call_all(method, *args, **kwargs, &block).first
|
187
195
|
when 'flushall', 'flushdb'
|
188
|
-
@node.
|
189
|
-
when '
|
190
|
-
when '
|
191
|
-
when '
|
196
|
+
@node.call_primaries(method, *args, **kwargs, &block).first
|
197
|
+
when 'ping' then @node.send_ping(method, *args, **kwargs, &block).first
|
198
|
+
when 'wait' then send_wait_command(method, *args, **kwargs, &block)
|
199
|
+
when 'keys' then @node.call_replicas(method, *args, **kwargs, &block).flatten.sort
|
200
|
+
when 'dbsize' then @node.call_replicas(method, *args, **kwargs, &block).sum
|
192
201
|
when 'scan' then _scan(*command, **kwargs)
|
193
|
-
when 'lastsave' then @node.call_all(method, *
|
194
|
-
when 'role' then @node.call_all(method, *
|
195
|
-
when 'config' then send_config_command(method, *
|
196
|
-
when 'client' then send_client_command(method, *
|
197
|
-
when 'cluster' then send_cluster_command(method, *
|
202
|
+
when 'lastsave' then @node.call_all(method, *args, **kwargs, &block).sort
|
203
|
+
when 'role' then @node.call_all(method, *args, **kwargs, &block)
|
204
|
+
when 'config' then send_config_command(method, *args, **kwargs, &block)
|
205
|
+
when 'client' then send_client_command(method, *args, **kwargs, &block)
|
206
|
+
when 'cluster' then send_cluster_command(method, *args, **kwargs, &block)
|
198
207
|
when 'readonly', 'readwrite', 'shutdown'
|
199
208
|
raise ::RedisClient::Cluster::OrchestrationCommandNotSupported, cmd
|
200
|
-
when 'memory' then send_memory_command(method, *
|
201
|
-
when 'script' then send_script_command(method, *
|
202
|
-
when 'pubsub' then send_pubsub_command(method, *
|
209
|
+
when 'memory' then send_memory_command(method, *args, **kwargs, &block)
|
210
|
+
when 'script' then send_script_command(method, *args, **kwargs, &block)
|
211
|
+
when 'pubsub' then send_pubsub_command(method, *args, **kwargs, &block)
|
203
212
|
when 'discard', 'exec', 'multi', 'unwatch'
|
204
213
|
raise ::RedisClient::Cluster::AmbiguousNodeError, cmd
|
205
214
|
else
|
206
215
|
node = assign_node(*command)
|
207
|
-
try_send(node, method, *
|
216
|
+
try_send(node, method, *args, **kwargs, &block)
|
208
217
|
end
|
209
|
-
rescue RedisClient::Cluster::
|
210
|
-
update_cluster_info!
|
211
|
-
raise
|
218
|
+
rescue RedisClient::Cluster::Node::ReloadNeeded
|
219
|
+
update_cluster_info!
|
220
|
+
raise ::RedisClient::Cluster::NodeMightBeDown
|
212
221
|
end
|
213
222
|
|
214
|
-
def send_wait_command(method, *
|
215
|
-
@node.
|
216
|
-
rescue RedisClient::Cluster::
|
217
|
-
raise if retry_count <= 0
|
223
|
+
def send_wait_command(method, *args, retry_count: 3, **kwargs, &block)
|
224
|
+
@node.call_primaries(method, *args, **kwargs, &block).sum
|
225
|
+
rescue RedisClient::Cluster::ErrorCollection => e
|
226
|
+
raise if retry_count <= 0
|
227
|
+
raise if e.errors.values.none? do |err|
|
228
|
+
err.message.include?('WAIT cannot be used with replica instances')
|
229
|
+
end
|
218
230
|
|
219
231
|
update_cluster_info!
|
220
232
|
retry_count -= 1
|
221
233
|
retry
|
222
234
|
end
|
223
235
|
|
224
|
-
def send_config_command(method, *
|
236
|
+
def send_config_command(method, *args, **kwargs, &block)
|
237
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
238
|
+
|
225
239
|
case command[1].to_s.downcase
|
226
240
|
when 'resetstat', 'rewrite', 'set'
|
227
|
-
@node.call_all(method, *
|
228
|
-
else assign_node(*command).send(method, *
|
241
|
+
@node.call_all(method, *args, **kwargs, &block).first
|
242
|
+
else assign_node(*command).send(method, *args, **kwargs, &block)
|
229
243
|
end
|
230
244
|
end
|
231
245
|
|
232
|
-
def send_memory_command(method, *
|
246
|
+
def send_memory_command(method, *args, **kwargs, &block)
|
247
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
248
|
+
|
233
249
|
case command[1].to_s.downcase
|
234
|
-
when 'stats' then @node.call_all(method, *
|
235
|
-
when 'purge' then @node.call_all(method, *
|
236
|
-
else assign_node(*command).send(method, *
|
250
|
+
when 'stats' then @node.call_all(method, *args, **kwargs, &block)
|
251
|
+
when 'purge' then @node.call_all(method, *args, **kwargs, &block).first
|
252
|
+
else assign_node(*command).send(method, *args, **kwargs, &block)
|
237
253
|
end
|
238
254
|
end
|
239
255
|
|
240
|
-
def send_client_command(method, *
|
256
|
+
def send_client_command(method, *args, **kwargs, &block)
|
257
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
258
|
+
|
241
259
|
case command[1].to_s.downcase
|
242
|
-
when 'list' then @node.call_all(method, *
|
260
|
+
when 'list' then @node.call_all(method, *args, **kwargs, &block).flatten
|
243
261
|
when 'pause', 'reply', 'setname'
|
244
|
-
@node.call_all(method, *
|
245
|
-
else assign_node(*command).send(method, *
|
262
|
+
@node.call_all(method, *args, **kwargs, &block).first
|
263
|
+
else assign_node(*command).send(method, *args, **kwargs, &block)
|
246
264
|
end
|
247
265
|
end
|
248
266
|
|
249
|
-
def send_cluster_command(method, *
|
267
|
+
def send_cluster_command(method, *args, **kwargs, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
268
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
250
269
|
subcommand = command[1].to_s.downcase
|
270
|
+
|
251
271
|
case subcommand
|
252
272
|
when 'addslots', 'delslots', 'failover', 'forget', 'meet', 'replicate',
|
253
273
|
'reset', 'set-config-epoch', 'setslot'
|
254
274
|
raise ::RedisClient::Cluster::OrchestrationCommandNotSupported, ['cluster', subcommand]
|
255
|
-
when 'saveconfig' then @node.call_all(method, *
|
256
|
-
|
275
|
+
when 'saveconfig' then @node.call_all(method, *args, **kwargs, &block).first
|
276
|
+
when 'getkeysinslot'
|
277
|
+
raise ArgumentError, command.join(' ') if command.size != 4
|
278
|
+
|
279
|
+
find_node(@node.find_node_key_of_replica(command[2])).send(method, *args, **kwargs, &block)
|
280
|
+
else assign_node(*command).send(method, *args, **kwargs, &block)
|
257
281
|
end
|
258
282
|
end
|
259
283
|
|
260
|
-
def send_script_command(method, *
|
284
|
+
def send_script_command(method, *args, **kwargs, &block)
|
285
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
286
|
+
|
261
287
|
case command[1].to_s.downcase
|
262
288
|
when 'debug', 'kill'
|
263
|
-
@node.call_all(method, *
|
289
|
+
@node.call_all(method, *args, **kwargs, &block).first
|
264
290
|
when 'flush', 'load'
|
265
|
-
@node.
|
266
|
-
else assign_node(*command).send(method, *
|
291
|
+
@node.call_primaries(method, *args, **kwargs, &block).first
|
292
|
+
else assign_node(*command).send(method, *args, **kwargs, &block)
|
267
293
|
end
|
268
294
|
end
|
269
295
|
|
270
|
-
def send_pubsub_command(method, *
|
296
|
+
def send_pubsub_command(method, *args, **kwargs, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
297
|
+
command = method == :blocking_call && args.size > 1 ? args[1..] : args
|
298
|
+
|
271
299
|
case command[1].to_s.downcase
|
272
|
-
when 'channels' then @node.call_all(method, *
|
300
|
+
when 'channels' then @node.call_all(method, *args, **kwargs, &block).flatten.uniq.sort
|
273
301
|
when 'numsub'
|
274
|
-
@node.call_all(method, *
|
302
|
+
@node.call_all(method, *args, **kwargs, &block).reject(&:empty?).map { |e| Hash[*e] }
|
275
303
|
.reduce({}) { |a, e| a.merge(e) { |_, v1, v2| v1 + v2 } }
|
276
|
-
when 'numpat' then @node.call_all(method, *
|
277
|
-
else assign_node(*command).send(method, *
|
304
|
+
when 'numpat' then @node.call_all(method, *args, **kwargs, &block).sum
|
305
|
+
else assign_node(*command).send(method, *args, **kwargs, &block)
|
278
306
|
end
|
279
307
|
end
|
280
308
|
|
@@ -344,44 +372,30 @@ class RedisClient
|
|
344
372
|
find_node(node_key)
|
345
373
|
end
|
346
374
|
|
347
|
-
def find_node_key(*command, primary_only: false)
|
375
|
+
def find_node_key(*command, primary_only: false)
|
348
376
|
key = @command.extract_first_key(command)
|
349
|
-
|
350
|
-
return @node.primary_node_keys.sample if @command.should_send_to_primary?(command) || primary_only
|
351
|
-
|
352
|
-
return @node.replica_node_keys.sample
|
353
|
-
end
|
354
|
-
|
355
|
-
slot = ::RedisClient::Cluster::KeySlotConverter.convert(key)
|
356
|
-
return unless @node.slot_exists?(slot)
|
377
|
+
slot = key.empty? ? nil : ::RedisClient::Cluster::KeySlotConverter.convert(key)
|
357
378
|
|
358
379
|
if @command.should_send_to_primary?(command) || primary_only
|
359
|
-
@node.find_node_key_of_primary(slot)
|
380
|
+
@node.find_node_key_of_primary(slot) || @node.primary_node_keys.sample
|
360
381
|
else
|
361
|
-
@node.find_node_key_of_replica(slot)
|
382
|
+
@node.find_node_key_of_replica(slot) || @node.replica_node_keys.sample
|
362
383
|
end
|
363
384
|
end
|
364
385
|
|
365
386
|
def find_node(node_key, retry_count: 3)
|
366
|
-
return @node.sample if node_key.nil?
|
367
|
-
|
368
387
|
@node.find_by(node_key)
|
369
388
|
rescue ::RedisClient::Cluster::Node::ReloadNeeded
|
370
|
-
raise
|
389
|
+
raise ::RedieClient::Cluster::NodeMightBeDown if retry_count <= 0
|
371
390
|
|
372
|
-
update_cluster_info!
|
391
|
+
update_cluster_info!
|
373
392
|
retry_count -= 1
|
374
393
|
retry
|
375
394
|
end
|
376
395
|
|
377
|
-
def update_cluster_info!
|
396
|
+
def update_cluster_info!
|
378
397
|
@mutex.synchronize do
|
379
|
-
|
380
|
-
host, port = ::RedisClient::Cluster::NodeKey.split(node_key)
|
381
|
-
@config.add_node(host, port)
|
382
|
-
end
|
383
|
-
|
384
|
-
@node.each(&:close)
|
398
|
+
close
|
385
399
|
@node = fetch_cluster_info!(@config, pool: @pool, **@client_kwargs)
|
386
400
|
end
|
387
401
|
end
|
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.0.
|
4
|
+
version: 0.0.9
|
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-06-
|
11
|
+
date: 2022-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|