redis-cluster-client 0.0.3 → 0.0.4

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: 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