redis-cluster-client 0.11.4 → 0.11.6

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: f72e0ed5a40d8d663d00a29ffb43ec046d911c73e514fa709f907eaf59d2e751
4
- data.tar.gz: 442e3c7ef0e59dbef1950eb661aaf4441226927d4c871ae9a81824b33c456c4e
3
+ metadata.gz: 9e31ae2691d5dac09f55bffb25f1a5af9f0f300d9b71246f998d7a18ad6d6d97
4
+ data.tar.gz: 7331c0ea5c04d95bb9325ad235edbede9fa872dacdcc1df2745214241600f7fa
5
5
  SHA512:
6
- metadata.gz: 3c06f2218983448bba3daef5209828aec9b236757094a9635e514519adf0757385f91c8c7d9a62a86d6eb9bf652e9b354a71c457a60208793c63ebd43c14c3d0
7
- data.tar.gz: 523b7c8b897329260cacf1ab03ba26f917aa8dea0a78682d3aeeb8da538bed87ee482ed4f8e8db6e8f1d63649447b664cd86360f0a7e8bb554f4457d451c0946
6
+ metadata.gz: f8752f06007254fd8c73716f3a93853062e8bb61d9381cdf66e56f705a4f7c391e0f2685ee2b75d97d2bd25aac815ae17997e0982b0774c78324b04637af1574
7
+ data.tar.gz: f995c63ae5e11ff31a0ce4feaef8c421620244c192d32ae3522a71ca62956b362962c15a87daa8c76c50018368c2851d0c99c83b6a061fa1ef7024da3df4e6fd
@@ -309,7 +309,7 @@ class RedisClient
309
309
  work_group.push(i, raw_client) do |client|
310
310
  regular_timeout = client.read_timeout
311
311
  client.read_timeout = @config.slow_command_timeout > 0.0 ? @config.slow_command_timeout : regular_timeout
312
- reply = client.call('CLUSTER', 'NODES')
312
+ reply = client.call_once('CLUSTER', 'NODES')
313
313
  client.read_timeout = regular_timeout
314
314
  parse_cluster_node_reply(reply)
315
315
  rescue StandardError => e
@@ -15,10 +15,7 @@ class RedisClient
15
15
  slot = find_slot(keys)
16
16
  raise ::RedisClient::Cluster::Transaction::ConsistencyError, "unsafe watch: #{keys.join(' ')}" if slot.nil?
17
17
 
18
- # We have not yet selected a node for this transaction, initially, which means we can handle
19
- # redirections freely initially (i.e. for the first WATCH call)
20
- node = @router.find_primary_node_by_slot(slot)
21
- handle_redirection(node, retry_count: 1) do |nd|
18
+ handle_redirection(slot, retry_count: 1) do |nd|
22
19
  nd.with do |c|
23
20
  c.ensure_connected_cluster_scoped(retryable: false) do
24
21
  c.call('ASKING') if @asking
@@ -45,10 +42,22 @@ class RedisClient
45
42
 
46
43
  private
47
44
 
48
- def handle_redirection(node, retry_count: 1, &blk)
49
- @router.handle_redirection(node, retry_count: retry_count) do |nd|
45
+ def handle_redirection(slot, retry_count: 1, &blk)
46
+ # We have not yet selected a node for this transaction, initially, which means we can handle
47
+ # redirections freely initially (i.e. for the first WATCH call)
48
+ node = @router.find_primary_node_by_slot(slot)
49
+ times_block_executed = 0
50
+ @router.handle_redirection(node, nil, retry_count: retry_count) do |nd|
51
+ times_block_executed += 1
50
52
  handle_asking_once(nd, &blk)
51
53
  end
54
+ rescue ::RedisClient::ConnectionError
55
+ # Deduct the number of retries that happened _inside_ router#handle_redirection from our remaining
56
+ # _external_ retries. Always deduct at least one in case handle_redirection raises without trying the block.
57
+ retry_count -= [times_block_executed, 1].min
58
+ raise if retry_count < 0
59
+
60
+ retry
52
61
  end
53
62
 
54
63
  def handle_asking_once(node)
@@ -35,11 +35,15 @@ class RedisClient
35
35
  # Ruby VM allocates 1 MB memory as a stack for a thread.
36
36
  # It is a fixed size but we can modify the size with some environment variables.
37
37
  # So it consumes memory 1 MB multiplied a number of workers.
38
- Thread.new(client, queue) do |pubsub, q|
38
+ Thread.new(client, queue, nil) do |pubsub, q, prev_err|
39
39
  loop do
40
40
  q << pubsub.next_event
41
+ prev_err = nil
41
42
  rescue StandardError => e
43
+ next sleep 0.005 if e.instance_of?(prev_err.class) && e.message == prev_err&.message
44
+
42
45
  q << e
46
+ prev_err = e
43
47
  end
44
48
  end
45
49
  end
@@ -160,7 +164,6 @@ class RedisClient
160
164
  @router.renew_cluster_state
161
165
  @state_dict.each_value(&:close)
162
166
  @state_dict.clear
163
- @queue.clear
164
167
  @commands.each { |command| _call(command) }
165
168
  break
166
169
  rescue ::RedisClient::ConnectionError, ::RedisClient::Cluster::NodeMightBeDown
@@ -90,7 +90,7 @@ class RedisClient
90
90
 
91
91
  # @see https://redis.io/docs/reference/cluster-spec/#redirection-and-resharding Redirection and resharding
92
92
  def try_send(node, method, command, args, retry_count: 3, &block)
93
- handle_redirection(node, retry_count: retry_count) do |on_node|
93
+ handle_redirection(node, command, retry_count: retry_count) do |on_node|
94
94
  if args.empty?
95
95
  # prevent memory allocation for variable-length args
96
96
  on_node.public_send(method, command, &block)
@@ -101,12 +101,12 @@ class RedisClient
101
101
  end
102
102
 
103
103
  def try_delegate(node, method, *args, retry_count: 3, **kwargs, &block)
104
- handle_redirection(node, retry_count: retry_count) do |on_node|
104
+ handle_redirection(node, nil, retry_count: retry_count) do |on_node|
105
105
  on_node.public_send(method, *args, **kwargs, &block)
106
106
  end
107
107
  end
108
108
 
109
- def handle_redirection(node, retry_count:) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
109
+ def handle_redirection(node, command, retry_count:) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
110
110
  yield node
111
111
  rescue ::RedisClient::CircuitBreaker::OpenCircuitError
112
112
  raise
@@ -134,6 +134,17 @@ class RedisClient
134
134
 
135
135
  retry_count -= 1
136
136
  renew_cluster_state
137
+
138
+ if retry_count >= 0
139
+ # Find the node to use for this command - if this fails for some reason, though, re-use
140
+ # the old node.
141
+ begin
142
+ node = find_node(find_node_key(command)) if command
143
+ rescue StandardError # rubocop:disable Lint/SuppressedException
144
+ end
145
+ retry
146
+ end
147
+
137
148
  retry if retry_count >= 0
138
149
  raise
139
150
  end
@@ -15,10 +15,10 @@ class RedisClient
15
15
 
16
16
  attr_reader :config
17
17
 
18
- def initialize(config, pool: nil, concurrency: nil, **kwargs)
19
- @config = config
18
+ def initialize(config = nil, pool: nil, concurrency: nil, **kwargs)
19
+ @config = config.nil? ? ClusterConfig.new(**kwargs) : config
20
20
  @concurrent_worker = ::RedisClient::Cluster::ConcurrentWorker.create(**(concurrency || {}))
21
- @command_builder = config.command_builder
21
+ @command_builder = @config.command_builder
22
22
 
23
23
  @pool = pool
24
24
  @kwargs = kwargs
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.11.4
4
+ version: 0.11.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: 2024-09-27 00:00:00.000000000 Z
11
+ date: 2024-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client