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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a4668f3eaba9c3053d1464bdf1dc85524e2ba43fdbb2ffbbadc46fb4759d5e6
4
- data.tar.gz: eba5280f698fe559a69cdeba28cef2c0fff87023fa78e7d098042d9cc6c036ac
3
+ metadata.gz: 0561fdd5885f8c6c5c5c100af032b867224eff3ed91b546b6885f8bf3bd76663
4
+ data.tar.gz: 1ebe59416fb043af9da7a926cd338ac260ce1a46e5220b46f7a6744c8f1b8c2b
5
5
  SHA512:
6
- metadata.gz: 989fd1b82d429ae6450a8c9e1555fc3635c1592c4d68744ad33df9cb26f5d222666fbeb077af99757c6305956936f44b8e38aef405c1a275c10e501559337934
7
- data.tar.gz: c0e88ca74a4d0ff70116969ea0722d1659858587c1cfe8a404edf41658c0b9a87e0f3651db02fe88ad6d099b2948814fcc9415aa793394fb4e75ebc5eef0acec
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
- @clients.each do |node_key, client|
222
- reply = yield(node_key, client)
223
- results[node_key] = reply unless reply.nil?
224
- rescue ::RedisClient::CommandError => e
225
- errors[node_key] = e
226
- next
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
@@ -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
- # TODO: use concurrency
45
- def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
46
- @grouped.each do |node_key, rows|
47
- node_key = node_key.nil? ? @client.instance_variable_get(:@node).primary_node_keys.sample : node_key
48
- replies = @client.send(:find_node, node_key).pipelined do |pipeline|
49
- rows.each do |row|
50
- case row[1]
51
- when :call then pipeline.call(*row[2], **row[3])
52
- when :call_once then pipeline.call_once(*row[2], **row[3])
53
- when :blocking_call then pipeline.blocking_call(row[2], *row[3], **row[4])
54
- else raise NotImplementedError, row[1]
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
- raise ReplySizeError, "commands: #{rows.size}, replies: #{replies.size}" if rows.size != replies.size
61
+ raise ReplySizeError, "commands: #{rows.size}, replies: #{replies.size}" if rows.size != replies.size
60
62
 
61
- rows.each_with_index { |row, idx| @replies[row.first] = replies[idx] }
63
+ rows.each_with_index { |row, idx| all_replies[row.first] = replies[idx] }
64
+ end
62
65
  end
63
66
 
64
- @replies
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
- return if key.empty?
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
- unless node_key.nil?
354
- host, port = ::RedisClient::Cluster::NodeKey.split(node_key)
355
- @config.add_node(host, port)
356
- end
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
- @node.each(&:close)
359
- @node = fetch_cluster_info!(@config, pool: @pool, **@client_kwargs)
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-cluster-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taishi Kasuga