redis-cluster-client 0.3.4 → 0.3.5

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: 458c3d9cc4d1f6595510663cede0403953b2555ace0d3cae814663b23f69f1cb
4
- data.tar.gz: 01d2a34641e298ff7e99cc5f9edbad4ed152e5ca4f18e16181b9a4b84a2492c2
3
+ metadata.gz: a697c2bd33f615cb435ee48c11c301bba56cad4eac139f30db70a183d888d891
4
+ data.tar.gz: 52200e9400bd7bd7fde2019c52b6cf1e26c6c019cbf1ed12a25c2167cd7ac129
5
5
  SHA512:
6
- metadata.gz: 3680e6b8b1594001060eb2dea29eb60f0779bba6a43350246b1d5c7e47b1bb1e04a6e1188ac87c1228adac21e86347cb3820679d6c92b693d7f7fedabba88402
7
- data.tar.gz: 21927b8a14e9ad075e3808e736789c4339af907f5d99e16806273f1553c505e7fc86faabfa067b98f2a3dd7d45a41fb0f89e780e08825aa9df4317531871da5d
6
+ metadata.gz: 05dc86fd1aa3cbf3cd3f0fa43d9d1c8463fcbe9e0ce1bcfe094f6095fd92d878a4bb21e6d6fa62203e91f3dc642e5869552f0b83d579cfa158b791501e1cb600
7
+ data.tar.gz: 8f80c5072d4d1bdbeb3e2cb4c9f92493537a6d9002edd71426598844ba28a497171c055135bb19a1d89a325c194026195100f9a0aea89c0beac3d8e9424f7f58
@@ -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
- latencies[node_key] = min
58
+ Thread.current.thread_variable_set(:latency, min)
59
59
  rescue StandardError
60
- latencies[node_key] = DUMMY_LATENCY_NSEC
60
+ Thread.current.thread_variable_set(:latency, DUMMY_LATENCY_NSEC)
61
61
  end
62
62
  end
63
63
 
64
- threads.each(&:join)
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 = Array.new(startup_size)
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
- node_info_list[i] = parse_node_info(reply)
51
+ Thread.current.thread_variable_set(:info, parse_node_info(reply))
52
52
  rescue StandardError => e
53
- errors[i] = e
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(&:join)
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.all?(&:nil?)
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
- results[node_key] = reply unless reply.nil?
253
+ Thread.current.thread_variable_set(:result, reply)
245
254
  rescue StandardError => e
246
- errors[node_key] = e
255
+ Thread.current.thread_variable_set(:error, e)
247
256
  end
248
257
  end
249
258
 
250
- threads.each(&:join)
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]
@@ -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
- add_line(node_key, [@size, :call_v, command, block])
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
- add_line(node_key, [@size, :call_v, command, block])
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
- add_line(node_key, [@size, :call_once_v, command, block])
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
- add_line(node_key, [@size, :call_once_v, command, block])
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
- add_line(node_key, [@size, :blocking_call_v, timeout, command, block])
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
- add_line(node_key, [@size, :blocking_call_v, timeout, command, block])
53
+ add_row(node_key, [@size, :blocking_call_v, timeout, command, block])
54
54
  end
55
55
 
56
56
  def empty?
@@ -59,44 +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 = Array.new(@size)
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).pipelined do |pipeline|
69
- rows.each do |row|
70
- case row.size
71
- when 4 then pipeline.send(row[1], row[2], &row[3])
72
- when 5 then pipeline.send(row[1], row[2], row[3], &row[4])
73
- end
74
- end
75
- end
76
-
67
+ replies = do_pipelining(router.find_node(node_key), rows)
77
68
  raise ReplySizeError, "commands: #{rows.size}, replies: #{replies.size}" if rows.size != replies.size
78
69
 
79
- rows.each_with_index { |row, idx| all_replies[row.first] = replies[idx] }
70
+ Thread.current.thread_variable_set(:rows, rows)
71
+ Thread.current.thread_variable_set(:replies, replies)
80
72
  rescue StandardError => e
81
- errors[node_key] = e
73
+ Thread.current.thread_variable_set(:node_key, node_key)
74
+ Thread.current.thread_variable_set(:error, e)
82
75
  end
83
76
  end
84
77
 
85
- threads.each(&:join)
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
86
88
  end
87
89
 
88
- return all_replies if errors.empty?
90
+ return all_replies if errors.nil?
89
91
 
90
92
  raise ::RedisClient::Cluster::ErrorCollection, errors
91
93
  end
92
94
 
93
95
  private
94
96
 
95
- def add_line(node_key, line)
97
+ def add_row(node_key, row)
96
98
  @grouped[node_key] = [] unless @grouped.key?(node_key)
97
- @grouped[node_key] << line
99
+ @grouped[node_key] << row
98
100
  @size += 1
99
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
100
113
  end
101
114
  end
102
115
  end
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
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-19 00:00:00.000000000 Z
11
+ date: 2022-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client