redis-cluster-client 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/redis_client/cluster/node.rb +17 -8
- data/lib/redis_client/cluster.rb +35 -24
- data/lib/redis_client/cluster_config.rb +5 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0561fdd5885f8c6c5c5c100af032b867224eff3ed91b546b6885f8bf3bd76663
|
4
|
+
data.tar.gz: 1ebe59416fb043af9da7a926cd338ac260ce1a46e5220b46f7a6744c8f1b8c2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86661400532550e005beb98e740e4939ffcf93c1b66fb47930bc2a5819f5dbba60e940c8e0183d312a6ce7cb55d1cc0634081029eb8e5c1b8f68ea2862d9e0df
|
7
|
+
data.tar.gz: 3629f63ed379946bc8951c57ada535573130e8db504a2f5b7644ef9091408ac3223c5b0a260b13d6b84ab889b3e47c4571bbc10f5b21ceaf6758dc60c28a00b3
|
@@ -79,6 +79,7 @@ class RedisClient
|
|
79
79
|
@slots = build_slot_node_mappings(node_info)
|
80
80
|
@replications = build_replication_mappings(node_info)
|
81
81
|
@clients = build_clients(options, pool: pool, **kwargs)
|
82
|
+
@mutex = Mutex.new
|
82
83
|
end
|
83
84
|
|
84
85
|
def inspect
|
@@ -101,6 +102,12 @@ class RedisClient
|
|
101
102
|
@clients.filter_map { |k, _| primary?(k) ? k : nil }.sort
|
102
103
|
end
|
103
104
|
|
105
|
+
def replica_node_keys
|
106
|
+
return primary_node_keys if replica_disabled?
|
107
|
+
|
108
|
+
@clients.filter_map { |k, _| replica?(k) ? k : nil }.sort
|
109
|
+
end
|
110
|
+
|
104
111
|
def find_by(node_key)
|
105
112
|
@clients.fetch(node_key)
|
106
113
|
rescue KeyError
|
@@ -163,7 +170,7 @@ class RedisClient
|
|
163
170
|
end
|
164
171
|
|
165
172
|
def update_slot(slot, node_key)
|
166
|
-
@slots[slot] = node_key
|
173
|
+
@mutex.synchronize { @slots[slot] = node_key }
|
167
174
|
end
|
168
175
|
|
169
176
|
private
|
@@ -217,15 +224,17 @@ class RedisClient
|
|
217
224
|
def try_map # rubocop:disable Metrics/MethodLength
|
218
225
|
errors = {}
|
219
226
|
results = {}
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
+
threads = @clients.map do |k, v|
|
228
|
+
Thread.new(k, v) do |node_key, client|
|
229
|
+
Thread.pass
|
230
|
+
reply = yield(node_key, client)
|
231
|
+
results[node_key] = reply unless reply.nil?
|
232
|
+
rescue ::RedisClient::CommandError => e
|
233
|
+
errors[node_key] = e
|
234
|
+
end
|
227
235
|
end
|
228
236
|
|
237
|
+
threads.each(&:join)
|
229
238
|
return results if errors.empty?
|
230
239
|
|
231
240
|
raise ::RedisClient::Cluster::CommandErrorCollection, errors
|
data/lib/redis_client/cluster.rb
CHANGED
@@ -15,7 +15,6 @@ class RedisClient
|
|
15
15
|
def initialize(client)
|
16
16
|
@client = client
|
17
17
|
@grouped = Hash.new([].freeze)
|
18
|
-
@replies = []
|
19
18
|
@size = 0
|
20
19
|
end
|
21
20
|
|
@@ -41,27 +40,32 @@ class RedisClient
|
|
41
40
|
@size.zero?
|
42
41
|
end
|
43
42
|
|
44
|
-
#
|
45
|
-
|
46
|
-
@grouped.
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
43
|
+
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
44
|
+
all_replies = []
|
45
|
+
threads = @grouped.map do |k, v|
|
46
|
+
Thread.new(@client, k, v) do |client, node_key, rows|
|
47
|
+
Thread.pass
|
48
|
+
|
49
|
+
node_key = node_key.nil? ? client.instance_variable_get(:@node).primary_node_keys.sample : node_key
|
50
|
+
replies = client.send(:find_node, node_key).pipelined do |pipeline|
|
51
|
+
rows.each do |row|
|
52
|
+
case row[1]
|
53
|
+
when :call then pipeline.call(*row[2], **row[3])
|
54
|
+
when :call_once then pipeline.call_once(*row[2], **row[3])
|
55
|
+
when :blocking_call then pipeline.blocking_call(row[2], *row[3], **row[4])
|
56
|
+
else raise NotImplementedError, row[1]
|
57
|
+
end
|
55
58
|
end
|
56
59
|
end
|
57
|
-
end
|
58
60
|
|
59
|
-
|
61
|
+
raise ReplySizeError, "commands: #{rows.size}, replies: #{replies.size}" if rows.size != replies.size
|
60
62
|
|
61
|
-
|
63
|
+
rows.each_with_index { |row, idx| all_replies[row.first] = replies[idx] }
|
64
|
+
end
|
62
65
|
end
|
63
66
|
|
64
|
-
|
67
|
+
threads.each(&:join)
|
68
|
+
all_replies
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
@@ -103,6 +107,7 @@ class RedisClient
|
|
103
107
|
@client_kwargs = kwargs
|
104
108
|
@node = fetch_cluster_info!(@config, pool: @pool, **@client_kwargs)
|
105
109
|
@command = ::RedisClient::Cluster::Command.load(@node)
|
110
|
+
@mutex = Mutex.new
|
106
111
|
end
|
107
112
|
|
108
113
|
def inspect
|
@@ -326,9 +331,13 @@ class RedisClient
|
|
326
331
|
find_node(node_key)
|
327
332
|
end
|
328
333
|
|
329
|
-
def find_node_key(*command, primary_only: false)
|
334
|
+
def find_node_key(*command, primary_only: false) # rubocop:disable Metrics/MethodLength
|
330
335
|
key = @command.extract_first_key(command)
|
331
|
-
|
336
|
+
if key.empty?
|
337
|
+
return @node.primary_node_keys.sample if @command.should_send_to_primary?(command) || primary_only
|
338
|
+
|
339
|
+
return @node.replica_node_keys.sample
|
340
|
+
end
|
332
341
|
|
333
342
|
slot = ::RedisClient::Cluster::KeySlotConverter.convert(key)
|
334
343
|
return unless @node.slot_exists?(slot)
|
@@ -350,13 +359,15 @@ class RedisClient
|
|
350
359
|
end
|
351
360
|
|
352
361
|
def update_cluster_info!(node_key = nil)
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
362
|
+
@mutex.synchronize do
|
363
|
+
unless node_key.nil?
|
364
|
+
host, port = ::RedisClient::Cluster::NodeKey.split(node_key)
|
365
|
+
@config.add_node(host, port)
|
366
|
+
end
|
357
367
|
|
358
|
-
|
359
|
-
|
368
|
+
@node.each(&:close)
|
369
|
+
@node = fetch_cluster_info!(@config, pool: @pool, **@client_kwargs)
|
370
|
+
end
|
360
371
|
end
|
361
372
|
end
|
362
373
|
end
|
@@ -15,6 +15,7 @@ class RedisClient
|
|
15
15
|
VALID_SCHEMES = [DEFAULT_SCHEME, SECURE_SCHEME].freeze
|
16
16
|
VALID_NODES_KEYS = %i[ssl username password host port db].freeze
|
17
17
|
MERGE_CONFIG_KEYS = %i[ssl username password].freeze
|
18
|
+
IGNORE_GENERIC_CONFIG_KEYS = %i[url host port path].freeze
|
18
19
|
|
19
20
|
InvalidClientConfigError = Class.new(::RedisClient::Error)
|
20
21
|
|
@@ -22,7 +23,9 @@ class RedisClient
|
|
22
23
|
@replica = true & replica
|
23
24
|
@fixed_hostname = fixed_hostname.to_s
|
24
25
|
@node_configs = build_node_configs(nodes.dup)
|
26
|
+
client_config = client_config.reject { |k, _| IGNORE_GENERIC_CONFIG_KEYS.include?(k) }
|
25
27
|
@client_config = merge_generic_config(client_config, @node_configs)
|
28
|
+
@mutex = Mutex.new
|
26
29
|
end
|
27
30
|
|
28
31
|
def inspect
|
@@ -51,11 +54,11 @@ class RedisClient
|
|
51
54
|
end
|
52
55
|
|
53
56
|
def update_node(addrs)
|
54
|
-
@node_configs = build_node_configs(addrs)
|
57
|
+
@mutex.synchronize { @node_configs = build_node_configs(addrs) }
|
55
58
|
end
|
56
59
|
|
57
60
|
def add_node(host, port)
|
58
|
-
@node_configs << { host: host, port: port }
|
61
|
+
@mutex.synchronize { @node_configs << { host: host, port: port } }
|
59
62
|
end
|
60
63
|
|
61
64
|
def dup
|