redis-cluster-client 0.3.3 → 0.3.5
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 +13 -6
- data/lib/redis_client/cluster/node/latency_replica.rb +9 -5
- data/lib/redis_client/cluster/node.rb +32 -14
- data/lib/redis_client/cluster/normalized_cmd_name.rb +67 -0
- data/lib/redis_client/cluster/pipeline.rb +36 -20
- data/lib/redis_client/cluster/router.rb +15 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a697c2bd33f615cb435ee48c11c301bba56cad4eac139f30db70a183d888d891
|
4
|
+
data.tar.gz: 52200e9400bd7bd7fde2019c52b6cf1e26c6c019cbf1ed12a25c2167cd7ac129
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05dc86fd1aa3cbf3cd3f0fa43d9d1c8463fcbe9e0ce1bcfe094f6095fd92d878a4bb21e6d6fa62203e91f3dc642e5869552f0b83d579cfa158b791501e1cb600
|
7
|
+
data.tar.gz: 8f80c5072d4d1bdbeb3e2cb4c9f92493537a6d9002edd71426598844ba28a497171c055135bb19a1d89a325c194026195100f9a0aea89c0beac3d8e9424f7f58
|
@@ -2,10 +2,13 @@
|
|
2
2
|
|
3
3
|
require 'redis_client'
|
4
4
|
require 'redis_client/cluster/errors'
|
5
|
+
require 'redis_client/cluster/normalized_cmd_name'
|
5
6
|
|
6
7
|
class RedisClient
|
7
8
|
class Cluster
|
8
9
|
class Command
|
10
|
+
EMPTY_STRING = ''
|
11
|
+
|
9
12
|
class << self
|
10
13
|
def load(nodes) # rubocop:disable Metrics/MethodLength
|
11
14
|
errors = []
|
@@ -29,7 +32,10 @@ class RedisClient
|
|
29
32
|
|
30
33
|
def parse_command_details(rows)
|
31
34
|
rows&.reject { |row| row[0].nil? }.to_h do |row|
|
32
|
-
[
|
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
|
+
]
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
@@ -40,7 +46,7 @@ class RedisClient
|
|
40
46
|
|
41
47
|
def extract_first_key(command)
|
42
48
|
i = determine_first_key_position(command)
|
43
|
-
return
|
49
|
+
return EMPTY_STRING if i == 0
|
44
50
|
|
45
51
|
key = (command[i].is_a?(Array) ? command[i].flatten.first : command[i]).to_s
|
46
52
|
hash_tag = extract_hash_tag(key)
|
@@ -56,7 +62,8 @@ class RedisClient
|
|
56
62
|
end
|
57
63
|
|
58
64
|
def exists?(name)
|
59
|
-
|
65
|
+
key = ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_name(name)
|
66
|
+
@details.key?(key)
|
60
67
|
end
|
61
68
|
|
62
69
|
private
|
@@ -72,14 +79,14 @@ class RedisClient
|
|
72
79
|
end
|
73
80
|
|
74
81
|
def dig_details(command, key)
|
75
|
-
name =
|
82
|
+
name = ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_command(command)
|
76
83
|
return if name.empty? || !@details.key?(name)
|
77
84
|
|
78
85
|
@details.fetch(name).fetch(key)
|
79
86
|
end
|
80
87
|
|
81
88
|
def determine_first_key_position(command) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
|
82
|
-
case
|
89
|
+
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_command(command)
|
83
90
|
when 'eval', 'evalsha', 'zinterstore', 'zunionstore' then 3
|
84
91
|
when 'object' then 2
|
85
92
|
when 'memory'
|
@@ -104,7 +111,7 @@ class RedisClient
|
|
104
111
|
s = key.index('{')
|
105
112
|
e = key.index('}', s.to_i + 1)
|
106
113
|
|
107
|
-
return
|
114
|
+
return EMPTY_STRING if s.nil? || e.nil?
|
108
115
|
|
109
116
|
key[s + 1..e - 1]
|
110
117
|
end
|
@@ -40,12 +40,12 @@ class RedisClient
|
|
40
40
|
private
|
41
41
|
|
42
42
|
def measure_latencies(clients) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
43
|
-
latencies =
|
44
|
-
|
43
|
+
latencies = nil
|
45
44
|
clients.each_slice(::RedisClient::Cluster::Node::MAX_THREADS) do |chuncked_clients|
|
46
45
|
threads = chuncked_clients.map do |k, v|
|
47
46
|
Thread.new(k, v) do |node_key, client|
|
48
47
|
Thread.pass
|
48
|
+
Thread.current.thread_variable_set(:node_key, node_key)
|
49
49
|
|
50
50
|
min = DUMMY_LATENCY_NSEC
|
51
51
|
MEASURE_ATTEMPT_COUNT.times do
|
@@ -55,13 +55,17 @@ class RedisClient
|
|
55
55
|
min = duration if duration < min
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
Thread.current.thread_variable_set(:latency, min)
|
59
59
|
rescue StandardError
|
60
|
-
|
60
|
+
Thread.current.thread_variable_set(:latency, DUMMY_LATENCY_NSEC)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
threads.each
|
64
|
+
threads.each do |t|
|
65
|
+
t.join
|
66
|
+
latencies ||= {}
|
67
|
+
latencies[t.thread_variable_get(:node_key)] = t.thread_variable_get(:latency)
|
68
|
+
end
|
65
69
|
end
|
66
70
|
|
67
71
|
latencies
|
@@ -39,27 +39,36 @@ class RedisClient
|
|
39
39
|
class << self
|
40
40
|
def load_info(options, **kwargs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
41
41
|
startup_size = options.size > MAX_STARTUP_SAMPLE ? MAX_STARTUP_SAMPLE : options.size
|
42
|
-
node_info_list =
|
43
|
-
errors = Array.new(startup_size)
|
42
|
+
node_info_list = errors = nil
|
44
43
|
startup_options = options.to_a.sample(MAX_STARTUP_SAMPLE).to_h
|
45
44
|
startup_nodes = ::RedisClient::Cluster::Node.new(startup_options, **kwargs)
|
46
45
|
startup_nodes.each_slice(MAX_THREADS).with_index do |chuncked_startup_nodes, chuncked_idx|
|
47
46
|
threads = chuncked_startup_nodes.each_with_index.map do |raw_client, idx|
|
48
47
|
Thread.new(raw_client, (MAX_THREADS * chuncked_idx) + idx) do |cli, i|
|
49
48
|
Thread.pass
|
49
|
+
Thread.current.thread_variable_set(:index, i)
|
50
50
|
reply = cli.call('CLUSTER', 'NODES')
|
51
|
-
|
51
|
+
Thread.current.thread_variable_set(:info, parse_node_info(reply))
|
52
52
|
rescue StandardError => e
|
53
|
-
|
53
|
+
Thread.current.thread_variable_set(:error, e)
|
54
54
|
ensure
|
55
55
|
cli&.close
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
threads.each
|
59
|
+
threads.each do |t|
|
60
|
+
t.join
|
61
|
+
if t.thread_variable?(:info)
|
62
|
+
node_info_list ||= Array.new(startup_size)
|
63
|
+
node_info_list[t.thread_variable_get(:index)] = t.thread_variable_get(:info)
|
64
|
+
elsif t.thread_variable?(:error)
|
65
|
+
errors ||= Array.new(startup_size)
|
66
|
+
errors[t.thread_variable_get(:index)] = t.thread_variable_get(:error)
|
67
|
+
end
|
68
|
+
end
|
60
69
|
end
|
61
70
|
|
62
|
-
raise ::RedisClient::Cluster::InitialSetupError, errors if node_info_list.
|
71
|
+
raise ::RedisClient::Cluster::InitialSetupError, errors if node_info_list.nil?
|
63
72
|
|
64
73
|
grouped = node_info_list.compact.group_by do |rows|
|
65
74
|
rows.sort_by { |row| row[:id] }
|
@@ -147,7 +156,7 @@ class RedisClient
|
|
147
156
|
|
148
157
|
def send_ping(method, command, args, &block)
|
149
158
|
result_values, errors = call_multiple_nodes(@topology.clients, method, command, args, &block)
|
150
|
-
return result_values if errors.empty?
|
159
|
+
return result_values if errors.nil? || errors.empty?
|
151
160
|
|
152
161
|
raise ReloadNeeded if errors.values.any?(::RedisClient::ConnectionError)
|
153
162
|
|
@@ -228,26 +237,35 @@ class RedisClient
|
|
228
237
|
|
229
238
|
def call_multiple_nodes!(clients, method, command, args, &block)
|
230
239
|
result_values, errors = call_multiple_nodes(clients, method, command, args, &block)
|
231
|
-
return result_values if errors.empty?
|
240
|
+
return result_values if errors.nil? || errors.empty?
|
232
241
|
|
233
242
|
raise ::RedisClient::Cluster::ErrorCollection, errors
|
234
243
|
end
|
235
244
|
|
236
|
-
def try_map(clients) # rubocop:disable Metrics/MethodLength
|
237
|
-
results =
|
238
|
-
errors = {}
|
245
|
+
def try_map(clients) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
246
|
+
results = errors = nil
|
239
247
|
clients.each_slice(MAX_THREADS) do |chuncked_clients|
|
240
248
|
threads = chuncked_clients.map do |k, v|
|
241
249
|
Thread.new(k, v) do |node_key, client|
|
242
250
|
Thread.pass
|
251
|
+
Thread.current.thread_variable_set(:node_key, node_key)
|
243
252
|
reply = yield(node_key, client)
|
244
|
-
|
253
|
+
Thread.current.thread_variable_set(:result, reply)
|
245
254
|
rescue StandardError => e
|
246
|
-
|
255
|
+
Thread.current.thread_variable_set(:error, e)
|
247
256
|
end
|
248
257
|
end
|
249
258
|
|
250
|
-
threads.each
|
259
|
+
threads.each do |t|
|
260
|
+
t.join
|
261
|
+
if t.thread_variable?(:result)
|
262
|
+
results ||= {}
|
263
|
+
results[t.thread_variable_get(:node_key)] = t.thread_variable_get(:result)
|
264
|
+
elsif t.thread_variable?(:error)
|
265
|
+
errors ||= {}
|
266
|
+
errors[t.thread_variable_get(:node_key)] = t.thread_variable_get(:error)
|
267
|
+
end
|
268
|
+
end
|
251
269
|
end
|
252
270
|
|
253
271
|
[results, errors]
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
class RedisClient
|
6
|
+
class Cluster
|
7
|
+
class NormalizedCmdName
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
EMPTY_STRING = ''
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@cache = {}
|
14
|
+
@mutex = Mutex.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_by_command(command)
|
18
|
+
get(command, index: 0)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_by_subcommand(command)
|
22
|
+
get(command, index: 1)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_by_name(name)
|
26
|
+
get(name, index: 0)
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
@mutex.synchronize { @cache.clear }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def get(command, index:)
|
36
|
+
name = extract_name(command, index: index)
|
37
|
+
return EMPTY_STRING if name.nil? || name.empty?
|
38
|
+
|
39
|
+
normalize(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def extract_name(command, index:)
|
43
|
+
case command
|
44
|
+
when String, Symbol then index.zero? ? command : nil
|
45
|
+
when Array then extract_name_from_array(command, index: index)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def extract_name_from_array(command, index:)
|
50
|
+
return if command.size - 1 < index
|
51
|
+
|
52
|
+
case e = command[index]
|
53
|
+
when String, Symbol then e
|
54
|
+
when Array then e[index]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def normalize(name)
|
59
|
+
return @cache[name] if @cache.key?(name)
|
60
|
+
return name.to_s.downcase if @mutex.locked?
|
61
|
+
|
62
|
+
@mutex.synchronize { @cache[name] = name.to_s.downcase }
|
63
|
+
@cache[name]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -20,37 +20,37 @@ class RedisClient
|
|
20
20
|
def call(*args, **kwargs, &block)
|
21
21
|
command = @command_builder.generate(args, kwargs)
|
22
22
|
node_key = @router.find_node_key(command, seed: @seed)
|
23
|
-
|
23
|
+
add_row(node_key, [@size, :call_v, command, block])
|
24
24
|
end
|
25
25
|
|
26
26
|
def call_v(args, &block)
|
27
27
|
command = @command_builder.generate(args)
|
28
28
|
node_key = @router.find_node_key(command, seed: @seed)
|
29
|
-
|
29
|
+
add_row(node_key, [@size, :call_v, command, block])
|
30
30
|
end
|
31
31
|
|
32
32
|
def call_once(*args, **kwargs, &block)
|
33
33
|
command = @command_builder.generate(args, kwargs)
|
34
34
|
node_key = @router.find_node_key(command, seed: @seed)
|
35
|
-
|
35
|
+
add_row(node_key, [@size, :call_once_v, command, block])
|
36
36
|
end
|
37
37
|
|
38
38
|
def call_once_v(args, &block)
|
39
39
|
command = @command_builder.generate(args)
|
40
40
|
node_key = @router.find_node_key(command, seed: @seed)
|
41
|
-
|
41
|
+
add_row(node_key, [@size, :call_once_v, command, block])
|
42
42
|
end
|
43
43
|
|
44
44
|
def blocking_call(timeout, *args, **kwargs, &block)
|
45
45
|
command = @command_builder.generate(args, kwargs)
|
46
46
|
node_key = @router.find_node_key(command, seed: @seed)
|
47
|
-
|
47
|
+
add_row(node_key, [@size, :blocking_call_v, timeout, command, block])
|
48
48
|
end
|
49
49
|
|
50
50
|
def blocking_call_v(timeout, args, &block)
|
51
51
|
command = @command_builder.generate(args)
|
52
52
|
node_key = @router.find_node_key(command, seed: @seed)
|
53
|
-
|
53
|
+
add_row(node_key, [@size, :blocking_call_v, timeout, command, block])
|
54
54
|
end
|
55
55
|
|
56
56
|
def empty?
|
@@ -59,41 +59,57 @@ class RedisClient
|
|
59
59
|
|
60
60
|
# TODO: https://github.com/redis-rb/redis-cluster-client/issues/37 handle redirections
|
61
61
|
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
62
|
-
all_replies =
|
63
|
-
errors = {}
|
62
|
+
all_replies = errors = nil
|
64
63
|
@grouped.each_slice(MAX_THREADS) do |chuncked_grouped|
|
65
64
|
threads = chuncked_grouped.map do |k, v|
|
66
65
|
Thread.new(@router, k, v) do |router, node_key, rows|
|
67
66
|
Thread.pass
|
68
|
-
replies = router.find_node(node_key)
|
69
|
-
rows.each do |(_size, *row, block)|
|
70
|
-
pipeline.send(*row, &block)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
67
|
+
replies = do_pipelining(router.find_node(node_key), rows)
|
74
68
|
raise ReplySizeError, "commands: #{rows.size}, replies: #{replies.size}" if rows.size != replies.size
|
75
69
|
|
76
|
-
rows
|
70
|
+
Thread.current.thread_variable_set(:rows, rows)
|
71
|
+
Thread.current.thread_variable_set(:replies, replies)
|
77
72
|
rescue StandardError => e
|
78
|
-
|
73
|
+
Thread.current.thread_variable_set(:node_key, node_key)
|
74
|
+
Thread.current.thread_variable_set(:error, e)
|
79
75
|
end
|
80
76
|
end
|
81
77
|
|
82
|
-
threads.each
|
78
|
+
threads.each do |t|
|
79
|
+
t.join
|
80
|
+
if t.thread_variable?(:replies)
|
81
|
+
all_replies ||= Array.new(@size)
|
82
|
+
t.thread_variable_get(:rows).each_with_index { |r, i| all_replies[r.first] = t.thread_variable_get(:replies)[i] }
|
83
|
+
elsif t.thread_variable?(:error)
|
84
|
+
errors ||= {}
|
85
|
+
errors[t.thread_variable_get(:node_key)] = t.thread_variable_get(:error)
|
86
|
+
end
|
87
|
+
end
|
83
88
|
end
|
84
89
|
|
85
|
-
return all_replies if errors.
|
90
|
+
return all_replies if errors.nil?
|
86
91
|
|
87
92
|
raise ::RedisClient::Cluster::ErrorCollection, errors
|
88
93
|
end
|
89
94
|
|
90
95
|
private
|
91
96
|
|
92
|
-
def
|
97
|
+
def add_row(node_key, row)
|
93
98
|
@grouped[node_key] = [] unless @grouped.key?(node_key)
|
94
|
-
@grouped[node_key] <<
|
99
|
+
@grouped[node_key] << row
|
95
100
|
@size += 1
|
96
101
|
end
|
102
|
+
|
103
|
+
def do_pipelining(node, rows)
|
104
|
+
node.pipelined do |pipeline|
|
105
|
+
rows.each do |row|
|
106
|
+
case row.size
|
107
|
+
when 4 then pipeline.send(row[1], row[2], &row[3])
|
108
|
+
when 5 then pipeline.send(row[1], row[2], row[3], &row[4])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
97
113
|
end
|
98
114
|
end
|
99
115
|
end
|
@@ -6,6 +6,7 @@ require 'redis_client/cluster/errors'
|
|
6
6
|
require 'redis_client/cluster/key_slot_converter'
|
7
7
|
require 'redis_client/cluster/node'
|
8
8
|
require 'redis_client/cluster/node_key'
|
9
|
+
require 'redis_client/cluster/normalized_cmd_name'
|
9
10
|
|
10
11
|
class RedisClient
|
11
12
|
class Cluster
|
@@ -25,7 +26,7 @@ class RedisClient
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
28
|
-
cmd =
|
29
|
+
cmd = ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_command(command)
|
29
30
|
case cmd
|
30
31
|
when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
|
31
32
|
@node.call_all(method, command, args, &block).first
|
@@ -65,7 +66,12 @@ class RedisClient
|
|
65
66
|
# @see https://redis.io/topics/cluster-spec#redirection-and-resharding
|
66
67
|
# Redirection and resharding
|
67
68
|
def try_send(node, method, command, args, retry_count: 3, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
68
|
-
|
69
|
+
if args.empty?
|
70
|
+
# prevent memory allocation for variable-length args
|
71
|
+
node.send(method, command, &block)
|
72
|
+
else
|
73
|
+
node.send(method, *args, command, &block)
|
74
|
+
end
|
69
75
|
rescue ::RedisClient::CommandError => e
|
70
76
|
raise if retry_count <= 0
|
71
77
|
|
@@ -193,7 +199,7 @@ class RedisClient
|
|
193
199
|
end
|
194
200
|
|
195
201
|
def send_config_command(method, command, args, &block)
|
196
|
-
case
|
202
|
+
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_subcommand(command)
|
197
203
|
when 'resetstat', 'rewrite', 'set'
|
198
204
|
@node.call_all(method, command, args, &block).first
|
199
205
|
else assign_node(command).send(method, *args, command, &block)
|
@@ -201,7 +207,7 @@ class RedisClient
|
|
201
207
|
end
|
202
208
|
|
203
209
|
def send_memory_command(method, command, args, &block)
|
204
|
-
case
|
210
|
+
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_subcommand(command)
|
205
211
|
when 'stats' then @node.call_all(method, command, args, &block)
|
206
212
|
when 'purge' then @node.call_all(method, command, args, &block).first
|
207
213
|
else assign_node(command).send(method, *args, command, &block)
|
@@ -209,7 +215,7 @@ class RedisClient
|
|
209
215
|
end
|
210
216
|
|
211
217
|
def send_client_command(method, command, args, &block)
|
212
|
-
case
|
218
|
+
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_subcommand(command)
|
213
219
|
when 'list' then @node.call_all(method, command, args, &block).flatten
|
214
220
|
when 'pause', 'reply', 'setname'
|
215
221
|
@node.call_all(method, command, args, &block).first
|
@@ -217,10 +223,8 @@ class RedisClient
|
|
217
223
|
end
|
218
224
|
end
|
219
225
|
|
220
|
-
def send_cluster_command(method, command, args, &block)
|
221
|
-
subcommand =
|
222
|
-
|
223
|
-
case subcommand
|
226
|
+
def send_cluster_command(method, command, args, &block)
|
227
|
+
case subcommand = ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_subcommand(command)
|
224
228
|
when 'addslots', 'delslots', 'failover', 'forget', 'meet', 'replicate',
|
225
229
|
'reset', 'set-config-epoch', 'setslot'
|
226
230
|
raise ::RedisClient::Cluster::OrchestrationCommandNotSupported, ['cluster', subcommand]
|
@@ -234,7 +238,7 @@ class RedisClient
|
|
234
238
|
end
|
235
239
|
|
236
240
|
def send_script_command(method, command, args, &block)
|
237
|
-
case
|
241
|
+
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_subcommand(command)
|
238
242
|
when 'debug', 'kill'
|
239
243
|
@node.call_all(method, command, args, &block).first
|
240
244
|
when 'flush', 'load'
|
@@ -244,7 +248,7 @@ class RedisClient
|
|
244
248
|
end
|
245
249
|
|
246
250
|
def send_pubsub_command(method, command, args, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
247
|
-
case
|
251
|
+
case ::RedisClient::Cluster::NormalizedCmdName.instance.get_by_subcommand(command)
|
248
252
|
when 'channels' then @node.call_all(method, command, args, &block).flatten.uniq.sort_by(&:to_s)
|
249
253
|
when 'numsub'
|
250
254
|
@node.call_all(method, command, args, &block).reject(&:empty?).map { |e| Hash[*e] }
|
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.5
|
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-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/redis_client/cluster/node/random_replica.rb
|
43
43
|
- lib/redis_client/cluster/node/replica_mixin.rb
|
44
44
|
- lib/redis_client/cluster/node_key.rb
|
45
|
+
- lib/redis_client/cluster/normalized_cmd_name.rb
|
45
46
|
- lib/redis_client/cluster/pipeline.rb
|
46
47
|
- lib/redis_client/cluster/pub_sub.rb
|
47
48
|
- lib/redis_client/cluster/router.rb
|