redis-cluster-client 0.4.16 → 0.4.17
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc35dc957459313cb97b78fae42fadb612788e8e65eb49449db24b66294057fa
|
4
|
+
data.tar.gz: 03cf3604892eb1a881123bdfeabaeac30816ed940a827c5390b2320b3e9e26f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f8de53c53938381fb88c53ac2f13e8b7a78a3ee5653493fe0496acebaf0da57b568fb8c4436f8d19a7ba84d55018d9e4786c3726af2586581d0e7daee7b383f
|
7
|
+
data.tar.gz: 7b65b9e12fd251ca8a6c278c4fb245fc08b114c9cbfac58f88e5aca81d8b9ac9aa4939ef9dbf2ee042f313764b3205a9490453b7a2310915338e50c2871e4c47
|
@@ -39,30 +39,27 @@ class RedisClient
|
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
|
-
def measure_latencies(clients)
|
42
|
+
def measure_latencies(clients)
|
43
43
|
clients.each_slice(::RedisClient::Cluster::Node::MAX_THREADS).each_with_object({}) do |chuncked_clients, acc|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
MEASURE_ATTEMPT_COUNT.times do
|
50
|
-
starting = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond)
|
51
|
-
client.call_once('PING')
|
52
|
-
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) - starting
|
53
|
-
min = duration if duration < min
|
54
|
-
end
|
55
|
-
|
56
|
-
Thread.current[:latency] = min
|
57
|
-
rescue StandardError
|
58
|
-
Thread.current[:latency] = DUMMY_LATENCY_MSEC
|
59
|
-
end
|
60
|
-
end
|
44
|
+
chuncked_clients
|
45
|
+
.map { |node_key, client| [node_key, build_thread_for_measuring_latency(client)] }
|
46
|
+
.each { |node_key, thread| acc[node_key] = thread.value }
|
47
|
+
end
|
48
|
+
end
|
61
49
|
|
62
|
-
|
63
|
-
|
64
|
-
|
50
|
+
def build_thread_for_measuring_latency(client)
|
51
|
+
Thread.new(client) do |cli|
|
52
|
+
min = DUMMY_LATENCY_MSEC
|
53
|
+
MEASURE_ATTEMPT_COUNT.times do
|
54
|
+
starting = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond)
|
55
|
+
cli.call_once('PING')
|
56
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond) - starting
|
57
|
+
min = duration if duration < min
|
65
58
|
end
|
59
|
+
|
60
|
+
min
|
61
|
+
rescue StandardError
|
62
|
+
DUMMY_LATENCY_MSEC
|
66
63
|
end
|
67
64
|
end
|
68
65
|
|
@@ -24,12 +24,12 @@ class RedisClient
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def build_clients(primary_node_keys, options, pool, **kwargs)
|
27
|
-
options.
|
27
|
+
options.to_h do |node_key, option|
|
28
28
|
option = option.merge(kwargs.reject { |k, _| ::RedisClient::Cluster::Node::IGNORE_GENERIC_CONFIG_KEYS.include?(k) })
|
29
29
|
config = ::RedisClient::Cluster::Node::Config.new(scale_read: !primary_node_keys.include?(node_key), **option)
|
30
30
|
client = pool.nil? ? config.new_client : config.new_pool(**pool)
|
31
31
|
[node_key, client]
|
32
|
-
end
|
32
|
+
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -94,28 +94,19 @@ class RedisClient
|
|
94
94
|
startup_options = options.to_a.sample(MAX_STARTUP_SAMPLE).to_h
|
95
95
|
startup_nodes = ::RedisClient::Cluster::Node.new(startup_options, **kwargs)
|
96
96
|
startup_nodes.each_slice(MAX_THREADS).with_index do |chuncked_startup_nodes, chuncked_idx|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
97
|
+
chuncked_startup_nodes
|
98
|
+
.each_with_index
|
99
|
+
.map { |raw_client, idx| [(MAX_THREADS * chuncked_idx) + idx, build_thread_for_cluster_node(raw_client)] }
|
100
|
+
.each do |i, t|
|
101
|
+
case v = t.value
|
102
|
+
when StandardError
|
103
|
+
errors ||= Array.new(startup_size)
|
104
|
+
errors[i] = v
|
105
|
+
else
|
106
|
+
node_info_list ||= Array.new(startup_size)
|
107
|
+
node_info_list[i] = v
|
108
|
+
end
|
106
109
|
end
|
107
|
-
end
|
108
|
-
|
109
|
-
threads.each do |t|
|
110
|
-
t.join
|
111
|
-
if t.key?(:info)
|
112
|
-
node_info_list ||= Array.new(startup_size)
|
113
|
-
node_info_list[t[:index]] = t[:info]
|
114
|
-
elsif t.key?(:error)
|
115
|
-
errors ||= Array.new(startup_size)
|
116
|
-
errors[t[:index]] = t[:error]
|
117
|
-
end
|
118
|
-
end
|
119
110
|
end
|
120
111
|
|
121
112
|
raise ::RedisClient::Cluster::InitialSetupError, errors if node_info_list.nil?
|
@@ -132,6 +123,17 @@ class RedisClient
|
|
132
123
|
|
133
124
|
private
|
134
125
|
|
126
|
+
def build_thread_for_cluster_node(raw_client)
|
127
|
+
Thread.new(raw_client) do |client|
|
128
|
+
reply = client.call('CLUSTER', 'NODES')
|
129
|
+
parse_cluster_node_reply(reply)
|
130
|
+
rescue StandardError => e
|
131
|
+
e
|
132
|
+
ensure
|
133
|
+
client&.close
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
135
137
|
# @see https://redis.io/commands/cluster-nodes/
|
136
138
|
# @see https://github.com/redis/redis/blob/78960ad57b8a5e6af743d789ed8fd767e37d42b8/src/cluster.c#L4660-L4683
|
137
139
|
def parse_cluster_node_reply(reply) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
@@ -331,33 +333,33 @@ class RedisClient
|
|
331
333
|
raise ::RedisClient::Cluster::ErrorCollection, errors
|
332
334
|
end
|
333
335
|
|
334
|
-
def try_map(clients
|
336
|
+
def try_map(clients, &block)
|
335
337
|
results = errors = nil
|
336
338
|
clients.each_slice(MAX_THREADS) do |chuncked_clients|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
t.join
|
349
|
-
if t.key?(:result)
|
350
|
-
results ||= {}
|
351
|
-
results[t[:node_key]] = t[:result]
|
352
|
-
elsif t.key?(:error)
|
353
|
-
errors ||= {}
|
354
|
-
errors[t[:node_key]] = t[:error]
|
339
|
+
chuncked_clients
|
340
|
+
.map { |node_key, client| [node_key, build_thread_for_command(node_key, client, &block)] }
|
341
|
+
.each do |node_key, thread|
|
342
|
+
case v = thread.value
|
343
|
+
when StandardError
|
344
|
+
errors ||= {}
|
345
|
+
errors[node_key] = v
|
346
|
+
else
|
347
|
+
results ||= {}
|
348
|
+
results[node_key] = v
|
349
|
+
end
|
355
350
|
end
|
356
|
-
end
|
357
351
|
end
|
358
352
|
|
359
353
|
[results, errors]
|
360
354
|
end
|
355
|
+
|
356
|
+
def build_thread_for_command(node_key, client)
|
357
|
+
Thread.new(node_key, client) do |nk, cli|
|
358
|
+
yield(nk, cli)
|
359
|
+
rescue StandardError => e
|
360
|
+
e
|
361
|
+
end
|
362
|
+
end
|
361
363
|
end
|
362
364
|
end
|
363
365
|
end
|
@@ -148,38 +148,23 @@ class RedisClient
|
|
148
148
|
def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
149
149
|
all_replies = errors = nil
|
150
150
|
@pipelines&.each_slice(MAX_THREADS) do |chuncked_pipelines|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
if t.key?(:replies)
|
168
|
-
all_replies ||= Array.new(@size)
|
169
|
-
@pipelines[t[:node_key]]
|
170
|
-
.outer_indices
|
171
|
-
.each_with_index { |outer, inner| all_replies[outer] = t[:replies][inner] }
|
172
|
-
elsif t.key?(:redirection_needed)
|
173
|
-
all_replies ||= Array.new(@size)
|
174
|
-
pipeline = @pipelines[t[:node_key]]
|
175
|
-
err = t[:redirection_needed]
|
176
|
-
err.indices.each { |i| err.replies[i] = handle_redirection(err.replies[i], pipeline, i) }
|
177
|
-
pipeline.outer_indices.each_with_index { |outer, inner| all_replies[outer] = err.replies[inner] }
|
178
|
-
elsif t.key?(:error)
|
179
|
-
errors ||= {}
|
180
|
-
errors[t[:node_key]] = t[:error]
|
151
|
+
chuncked_pipelines
|
152
|
+
.map { |node_key, pipeline| [node_key, build_thread_for_pipeline(@router, node_key, pipeline)] }
|
153
|
+
.each do |node_key, thread|
|
154
|
+
case v = thread.value
|
155
|
+
when ::RedisClient::Cluster::Pipeline::RedirectionNeeded
|
156
|
+
all_replies ||= Array.new(@size)
|
157
|
+
pipeline = @pipelines[node_key]
|
158
|
+
v.indices.each { |i| v.replies[i] = handle_redirection(v.replies[i], pipeline, i) }
|
159
|
+
pipeline.outer_indices.each_with_index { |outer, inner| all_replies[outer] = v.replies[inner] }
|
160
|
+
when StandardError
|
161
|
+
errors ||= {}
|
162
|
+
errors[node_key] = v
|
163
|
+
else
|
164
|
+
all_replies ||= Array.new(@size)
|
165
|
+
@pipelines[node_key].outer_indices.each_with_index { |outer, inner| all_replies[outer] = v[inner] }
|
166
|
+
end
|
181
167
|
end
|
182
|
-
end
|
183
168
|
end
|
184
169
|
|
185
170
|
raise ::RedisClient::Cluster::ErrorCollection, errors unless errors.nil?
|
@@ -197,6 +182,17 @@ class RedisClient
|
|
197
182
|
@pipelines[node_key]
|
198
183
|
end
|
199
184
|
|
185
|
+
def build_thread_for_pipeline(router, node_key, pipeline)
|
186
|
+
Thread.new(router, node_key, pipeline) do |rt, nk, pl|
|
187
|
+
replies = do_pipelining(rt.find_node(nk), pl)
|
188
|
+
raise ReplySizeError, "commands: #{pl._size}, replies: #{replies.size}" if pl._size != replies.size
|
189
|
+
|
190
|
+
replies
|
191
|
+
rescue StandardError => e
|
192
|
+
e
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
200
196
|
def do_pipelining(client, pipeline)
|
201
197
|
case client
|
202
198
|
when ::RedisClient then send_pipeline(client, pipeline)
|
@@ -24,7 +24,7 @@ class RedisClient
|
|
24
24
|
@worker = subscribe(@client, timeout) if @worker.nil?
|
25
25
|
return if @worker.alive?
|
26
26
|
|
27
|
-
message = @worker
|
27
|
+
message = @worker.value
|
28
28
|
@worker = nil
|
29
29
|
message
|
30
30
|
end
|
@@ -33,9 +33,9 @@ class RedisClient
|
|
33
33
|
|
34
34
|
def subscribe(client, timeout)
|
35
35
|
Thread.new(client, timeout) do |pubsub, to|
|
36
|
-
|
36
|
+
pubsub.next_event(to)
|
37
37
|
rescue StandardError => e
|
38
|
-
|
38
|
+
e
|
39
39
|
end
|
40
40
|
end
|
41
41
|
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.4.
|
4
|
+
version: 0.4.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Taishi Kasuga
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|
@@ -69,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '0'
|
71
71
|
requirements: []
|
72
|
-
rubygems_version: 3.4.
|
72
|
+
rubygems_version: 3.4.19
|
73
73
|
signing_key:
|
74
74
|
specification_version: 4
|
75
75
|
summary: A Redis cluster client for Ruby
|