Skip to content

Commit 128c747

Browse files
authored
perf: make dedicated actions definition static (#422)
1 parent c84f6fd commit 128c747

File tree

2 files changed

+49
-59
lines changed

2 files changed

+49
-59
lines changed

lib/redis_client/cluster.rb

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ def initialize(config = nil, pool: nil, concurrency: nil, **kwargs)
1919
@config = config.nil? ? ClusterConfig.new(**kwargs) : config
2020
@concurrent_worker = ::RedisClient::Cluster::ConcurrentWorker.create(**(concurrency || {}))
2121
@command_builder = @config.command_builder
22-
2322
@pool = pool
2423
@kwargs = kwargs
2524
@router = nil

lib/redis_client/cluster/router.rb

+49-58
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,57 @@ class Cluster
1717
class Router
1818
ZERO_CURSOR_FOR_SCAN = '0'
1919
TSF = ->(f, x) { f.nil? ? x : f.call(x) }.curry
20+
DEDICATED_ACTIONS = lambda do # rubocop:disable Metrics/BlockLength
21+
action = Struct.new('RedisCommandRoutingAction', :method_name, :reply_transformer, keyword_init: true)
22+
pick_first = ->(reply) { reply.first } # rubocop:disable Style/SymbolProc
23+
multiple_key_action = action.new(method_name: :send_multiple_keys_command)
24+
all_node_first_action = action.new(method_name: :send_command_to_all_nodes, reply_transformer: pick_first)
25+
primary_first_action = action.new(method_name: :send_command_to_primaries, reply_transformer: pick_first)
26+
not_supported_action = action.new(method_name: :fail_not_supported_command)
27+
keyless_action = action.new(method_name: :fail_keyless_command)
28+
{
29+
'ping' => action.new(method_name: :send_ping_command, reply_transformer: pick_first),
30+
'wait' => action.new(method_name: :send_wait_command),
31+
'keys' => action.new(method_name: :send_command_to_replicas, reply_transformer: ->(reply) { reply.flatten.sort_by(&:to_s) }),
32+
'dbsize' => action.new(method_name: :send_command_to_replicas, reply_transformer: ->(reply) { reply.select { |e| e.is_a?(Integer) }.sum }),
33+
'scan' => action.new(method_name: :send_scan_command),
34+
'lastsave' => action.new(method_name: :send_command_to_all_nodes, reply_transformer: ->(reply) { reply.sort_by(&:to_i) }),
35+
'role' => action.new(method_name: :send_command_to_all_nodes),
36+
'config' => action.new(method_name: :send_config_command),
37+
'client' => action.new(method_name: :send_client_command),
38+
'cluster' => action.new(method_name: :send_cluster_command),
39+
'memory' => action.new(method_name: :send_memory_command),
40+
'script' => action.new(method_name: :send_script_command),
41+
'pubsub' => action.new(method_name: :send_pubsub_command),
42+
'watch' => action.new(method_name: :send_watch_command),
43+
'mget' => multiple_key_action,
44+
'mset' => multiple_key_action,
45+
'del' => multiple_key_action,
46+
'acl' => all_node_first_action,
47+
'auth' => all_node_first_action,
48+
'bgrewriteaof' => all_node_first_action,
49+
'bgsave' => all_node_first_action,
50+
'quit' => all_node_first_action,
51+
'save' => all_node_first_action,
52+
'flushall' => primary_first_action,
53+
'flushdb' => primary_first_action,
54+
'readonly' => not_supported_action,
55+
'readwrite' => not_supported_action,
56+
'shutdown' => not_supported_action,
57+
'discard' => keyless_action,
58+
'exec' => keyless_action,
59+
'multi' => keyless_action,
60+
'unwatch' => keyless_action
61+
}.each_with_object({}) do |(k, v), acc|
62+
acc[k] = v
63+
acc[k.upcase] = v
64+
end
65+
end.call.freeze
2066

21-
private_constant :ZERO_CURSOR_FOR_SCAN, :TSF
67+
private_constant :ZERO_CURSOR_FOR_SCAN, :TSF, :DEDICATED_ACTIONS
2268

2369
attr_reader :config
2470

25-
Action = Struct.new(
26-
'RedisCommandRoutingAction',
27-
:method_name,
28-
:reply_transformer,
29-
keyword_init: true
30-
)
31-
3271
def initialize(config, concurrent_worker, pool: nil, **kwargs)
3372
@config = config
3473
@concurrent_worker = concurrent_worker
@@ -38,16 +77,15 @@ def initialize(config, concurrent_worker, pool: nil, **kwargs)
3877
@node.reload!
3978
@command = ::RedisClient::Cluster::Command.load(@node.replica_clients.shuffle, slow_command_timeout: config.slow_command_timeout)
4079
@command_builder = @config.command_builder
41-
@dedicated_actions = build_dedicated_actions
4280
rescue ::RedisClient::Cluster::InitialSetupError => e
4381
e.with_config(config)
4482
raise
4583
end
4684

4785
def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
48-
return assign_node_and_send_command(method, command, args, &block) unless @dedicated_actions.key?(command.first)
86+
return assign_node_and_send_command(method, command, args, &block) unless DEDICATED_ACTIONS.key?(command.first)
4987

50-
action = @dedicated_actions[command.first]
88+
action = DEDICATED_ACTIONS[command.first]
5189
return send(action.method_name, method, command, args, &block) if action.reply_transformer.nil?
5290

5391
reply = send(action.method_name, method, command, args)
@@ -257,53 +295,6 @@ def close
257295

258296
private
259297

260-
def build_dedicated_actions # rubocop:disable Metrics/AbcSize
261-
pick_first = ->(reply) { reply.first } # rubocop:disable Style/SymbolProc
262-
multiple_key_action = Action.new(method_name: :send_multiple_keys_command)
263-
all_node_first_action = Action.new(method_name: :send_command_to_all_nodes, reply_transformer: pick_first)
264-
primary_first_action = Action.new(method_name: :send_command_to_primaries, reply_transformer: pick_first)
265-
not_supported_action = Action.new(method_name: :fail_not_supported_command)
266-
keyless_action = Action.new(method_name: :fail_keyless_command)
267-
actions = {
268-
'ping' => Action.new(method_name: :send_ping_command, reply_transformer: pick_first),
269-
'wait' => Action.new(method_name: :send_wait_command),
270-
'keys' => Action.new(method_name: :send_command_to_replicas, reply_transformer: ->(reply) { reply.flatten.sort_by(&:to_s) }),
271-
'dbsize' => Action.new(method_name: :send_command_to_replicas, reply_transformer: ->(reply) { reply.select { |e| e.is_a?(Integer) }.sum }),
272-
'scan' => Action.new(method_name: :send_scan_command),
273-
'lastsave' => Action.new(method_name: :send_command_to_all_nodes, reply_transformer: ->(reply) { reply.sort_by(&:to_i) }),
274-
'role' => Action.new(method_name: :send_command_to_all_nodes),
275-
'config' => Action.new(method_name: :send_config_command),
276-
'client' => Action.new(method_name: :send_client_command),
277-
'cluster' => Action.new(method_name: :send_cluster_command),
278-
'memory' => Action.new(method_name: :send_memory_command),
279-
'script' => Action.new(method_name: :send_script_command),
280-
'pubsub' => Action.new(method_name: :send_pubsub_command),
281-
'watch' => Action.new(method_name: :send_watch_command),
282-
'mget' => multiple_key_action,
283-
'mset' => multiple_key_action,
284-
'del' => multiple_key_action,
285-
'acl' => all_node_first_action,
286-
'auth' => all_node_first_action,
287-
'bgrewriteaof' => all_node_first_action,
288-
'bgsave' => all_node_first_action,
289-
'quit' => all_node_first_action,
290-
'save' => all_node_first_action,
291-
'flushall' => primary_first_action,
292-
'flushdb' => primary_first_action,
293-
'readonly' => not_supported_action,
294-
'readwrite' => not_supported_action,
295-
'shutdown' => not_supported_action,
296-
'discard' => keyless_action,
297-
'exec' => keyless_action,
298-
'multi' => keyless_action,
299-
'unwatch' => keyless_action
300-
}.freeze
301-
actions.each_with_object({}) do |(k, v), acc|
302-
acc[k] = v
303-
acc[k.upcase] = v
304-
end.freeze
305-
end
306-
307298
def send_command_to_all_nodes(method, command, args, &block)
308299
@node.call_all(method, command, args, &block)
309300
end

0 commit comments

Comments
 (0)