redis-cluster-client 0.0.5 → 0.0.6

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: 6fce5f4a15cfcab3d7cca37052e9f85ad45abcee8f4de9e458fc560a01382842
4
- data.tar.gz: 2da9fb7a3ae8836dd7606fbfd05e33f423529716493d3bb8fccd6d01bae10bc3
3
+ metadata.gz: fde84481c2ca9680670f252a002391a34ae793148a21a8e02086d199412a53ab
4
+ data.tar.gz: 5af188432f9ae5e76c13d0dd174c25cde4b98d1de49efeb97e2a809bd111a9a6
5
5
  SHA512:
6
- metadata.gz: fd4b929261fe0a50f4b13fe4963550e7b8c1197ee4f813a464b309140b29d7cc75a95259f100481d2f7e5a958a98608aca980e8308dca125200c1acb4e506e06
7
- data.tar.gz: b41237f574ca12b3826e8d869f3ea3251a0acb41961fb009efe7bb5d2f07517b17cae80c5161da91603b4586a63beef11ba618b6386cfd684012cc7fa09752d1
6
+ metadata.gz: f26dc7bb447ee70742efc90344758ad3058cd0d1506ad8576637b7e9ad296a806d7e15e3b824cead0fb2313140dea00f6f579a15803399c16257ac347c45085f
7
+ data.tar.gz: 06f43e223a53d9ada0803f7292bc1ca58505fb3c341fd7643eb6cf0eff73bebe4ecd2022b0a1b59af81dda879a9d8a9b078107181ff45037773382dada321597
@@ -171,6 +171,12 @@ class RedisClient
171
171
  @mutex.synchronize { @slots[slot] = node_key }
172
172
  end
173
173
 
174
+ def replicated?(primary_node_key, replica_node_key)
175
+ return false if @replications.nil? || @replications.size.zero?
176
+
177
+ @replications.fetch(primary_node_key).include?(replica_node_key)
178
+ end
179
+
174
180
  private
175
181
 
176
182
  def replica_disabled?
@@ -182,7 +188,9 @@ class RedisClient
182
188
  end
183
189
 
184
190
  def replica?(node_key)
185
- !(@replications.nil? || @replications.size.zero?) && !@replications.key?(node_key)
191
+ return false if @replications.nil? || @replications.size.zero?
192
+
193
+ !@replications.key?(node_key)
186
194
  end
187
195
 
188
196
  def build_slot_node_mappings(node_info)
@@ -196,11 +204,12 @@ class RedisClient
196
204
  slots
197
205
  end
198
206
 
199
- def build_replication_mappings(node_info)
207
+ def build_replication_mappings(node_info) # rubocop:disable Metrics/AbcSize
200
208
  dict = node_info.to_h { |info| [info[:id], info] }
201
209
  node_info.each_with_object(Hash.new { |h, k| h[k] = [] }) do |info, acc|
202
210
  primary_info = dict[info[:primary_id]]
203
211
  acc[primary_info[:node_key]] << info[:node_key] unless primary_info.nil?
212
+ acc[info[:node_key]] if info[:role] == 'master' # for the primary which have no replicas
204
213
  end
205
214
  end
206
215
 
@@ -40,6 +40,7 @@ class RedisClient
40
40
  @size.zero?
41
41
  end
42
42
 
43
+ # TODO: https://github.com/redis-rb/redis-cluster-client/issues/37
43
44
  def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
44
45
  all_replies = Array.new(@size)
45
46
  threads = @grouped.map do |k, v|
@@ -181,11 +182,11 @@ class RedisClient
181
182
  def send_command(method, *command, **kwargs, &block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
182
183
  cmd = command.first.to_s.downcase
183
184
  case cmd
184
- when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
185
+ when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save', 'ping'
185
186
  @node.call_all(method, *command, **kwargs, &block).first
186
187
  when 'flushall', 'flushdb'
187
188
  @node.call_primary(method, *command, **kwargs, &block).first
188
- when 'wait' then @node.call_primary(method, *command, **kwargs, &block).sum
189
+ when 'wait' then send_wait_command(method, *command, **kwargs, &block)
189
190
  when 'keys' then @node.call_replica(method, *command, **kwargs, &block).flatten.sort
190
191
  when 'dbsize' then @node.call_replica(method, *command, **kwargs, &block).sum
191
192
  when 'scan' then _scan(*command, **kwargs)
@@ -205,6 +206,19 @@ class RedisClient
205
206
  node = assign_node(*command)
206
207
  try_send(node, method, *command, **kwargs, &block)
207
208
  end
209
+ rescue RedisClient::Cluster::CommandErrorCollection => e
210
+ update_cluster_info! if e.errors.values.map(&:class).any?(::RedisClient::ConnectionError)
211
+ raise
212
+ end
213
+
214
+ def send_wait_command(method, *command, retry_count: 3, **kwargs, &block)
215
+ @node.call_primary(method, *command, **kwargs, &block).sum
216
+ rescue RedisClient::Cluster::CommandErrorCollection => e
217
+ raise if retry_count <= 0 || e.errors.values.map(&:message).grep(/ERR WAIT cannot be used with replica instances/).empty?
218
+
219
+ update_cluster_info!
220
+ retry_count -= 1
221
+ retry
208
222
  end
209
223
 
210
224
  def send_config_command(method, *command, **kwargs, &block)
@@ -266,18 +280,16 @@ class RedisClient
266
280
 
267
281
  # @see https://redis.io/topics/cluster-spec#redirection-and-resharding
268
282
  # Redirection and resharding
269
- def try_send(node, method, *args, retry_count: 3, **kwargs, &block) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
283
+ def try_send(node, method, *args, retry_count: 3, **kwargs, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
270
284
  node.send(method, *args, **kwargs, &block)
271
285
  rescue ::RedisClient::CommandError => e
272
- if e.message.start_with?(REPLY_MOVED)
273
- raise if retry_count <= 0
286
+ raise if retry_count <= 0
274
287
 
288
+ if e.message.start_with?(REPLY_MOVED)
275
289
  node = assign_redirection_node(e.message)
276
290
  retry_count -= 1
277
291
  retry
278
292
  elsif e.message.start_with?(REPLY_ASK)
279
- raise if retry_count <= 0
280
-
281
293
  node = assign_asking_node(e.message)
282
294
  node.call(CMD_ASKING)
283
295
  retry_count -= 1
@@ -286,8 +298,11 @@ class RedisClient
286
298
  raise
287
299
  end
288
300
  rescue ::RedisClient::ConnectionError
301
+ raise if retry_count <= 0
302
+
289
303
  update_cluster_info!
290
- raise
304
+ retry_count -= 1
305
+ retry
291
306
  end
292
307
 
293
308
  def _scan(*command, **kwargs) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
@@ -347,13 +362,16 @@ class RedisClient
347
362
  end
348
363
  end
349
364
 
350
- def find_node(node_key)
365
+ def find_node(node_key, retry_count: 3)
351
366
  return @node.sample if node_key.nil?
352
367
 
353
368
  @node.find_by(node_key)
354
369
  rescue ::RedisClient::Cluster::Node::ReloadNeeded
370
+ raise(::RedisClient::ConnectionError, 'unstable cluster state') if retry_count <= 0
371
+
355
372
  update_cluster_info!(node_key)
356
- @node.find_by(node_key)
373
+ retry_count -= 1
374
+ retry
357
375
  end
358
376
 
359
377
  def update_cluster_info!(node_key = nil)
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.0.5
4
+ version: 0.0.6
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-06-18 00:00:00.000000000 Z
11
+ date: 2022-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client