redis-cluster-client 0.16.4 → 0.16.5

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: 80b5e1d6525a06ecf8747239269b110528bf9efc99ff3424108033c85cdc011a
4
- data.tar.gz: 35b5aba54bc61e3731509c7ba3959289ddcfb30e40193f365fc26f62f4c7e60d
3
+ metadata.gz: ee5d5f4c7bb89d0899ef2c3aec48503580d01a1e84a369f1e9ee0c1f60011f15
4
+ data.tar.gz: b17966f3f4c74ce89005b49188d769c4e8b6e399d6d65e0c4d68e14868cee9c7
5
5
  SHA512:
6
- metadata.gz: ab546dc6dc75d1ec1733c5cd5f29a451881d71db8c21e587be92ab77c2f12f602100468626b742a1d87caa98aa27699906f9aefd7d9cff02512c3be1e355bdd4
7
- data.tar.gz: 741326d16416834940e08c7084019080188d3e6b252c6dafdf3037bb9a40e2f9aafc0dc771fce7ac4edbb50af6d630067fb3646f4e7f1016ab72d7ceafb04940
6
+ metadata.gz: 580dbda062e93296be5869169a3f8f4d389f7bc7aba34cb473cc1a1877cd8a552a29617bf6e09cc2bea8e372cbf895f28ffd086bf75ce986a2dd448bd7170dae
7
+ data.tar.gz: d3abefad63034a97613319637fe617b66f64b2053f67ed8c6de7d81350976645c0eec250037fd100b0a4d5e518c3674c96e07fb043c56ffd327a8e918626405d
@@ -109,7 +109,7 @@ class RedisClient
109
109
  key_step: row[5],
110
110
  write?: writable,
111
111
  readonly?: row[2].include?('readonly')
112
- )
112
+ ).freeze
113
113
  end.freeze || EMPTY_HASH
114
114
  end
115
115
  end
@@ -53,15 +53,10 @@ class RedisClient
53
53
  end
54
54
 
55
55
  class CharArray
56
- BASE = ''
57
- PADDING = '0'
58
-
59
- private_constant :BASE, :PADDING
60
-
61
56
  def initialize(size, elements)
62
57
  @elements = elements
63
- @string = String.new(BASE, encoding: Encoding::BINARY, capacity: size)
64
- size.times { @string << PADDING }
58
+ @string = String.new('', encoding: Encoding::BINARY, capacity: size)
59
+ size.times { @string << 0xff }
65
60
  end
66
61
 
67
62
  def [](index)
@@ -314,7 +309,6 @@ class RedisClient
314
309
  e
315
310
  ensure
316
311
  client.read_timeout = regular_timeout
317
- client&.close
318
312
  end
319
313
  end
320
314
 
@@ -378,7 +372,7 @@ class RedisClient
378
372
  config_epoch: fields[6],
379
373
  link_state: fields[7],
380
374
  slots: slots
381
- )
375
+ ).freeze
382
376
  end
383
377
  end
384
378
 
@@ -398,7 +392,7 @@ class RedisClient
398
392
  role: role,
399
393
  primary_id: role == 'master' ? EMPTY_STRING : primary_id,
400
394
  slots: role == 'master' ? slots : EMPTY_ARRAY
401
- )
395
+ ).freeze
402
396
  end
403
397
  end
404
398
  end
@@ -422,7 +416,7 @@ class RedisClient
422
416
  role: role == 'master' ? role : 'slave',
423
417
  primary_id: role == 'master' ? EMPTY_STRING : primary_id,
424
418
  slots: role == 'master' ? shard.fetch('slots').each_slice(2).to_a.freeze : EMPTY_ARRAY
425
- )
419
+ ).freeze
426
420
  end
427
421
  end
428
422
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'redis_client'
4
4
  require 'redis_client/cluster/transaction'
5
+ require 'redis_client/cluster/error_identification'
5
6
 
6
7
  class RedisClient
7
8
  class Cluster
@@ -54,7 +55,7 @@ class RedisClient
54
55
  rescue ::RedisClient::ConnectionError
55
56
  # Deduct the number of retries that happened _inside_ router#handle_redirection from our remaining
56
57
  # _external_ retries. Always deduct at least one in case handle_redirection raises without trying the block.
57
- retry_count -= times_block_executed == 0 ? 1 : [times_block_executed, 1].min
58
+ retry_count -= times_block_executed > 1 ? times_block_executed : 1
58
59
  raise if retry_count < 0
59
60
 
60
61
  retry
@@ -23,10 +23,6 @@ class RedisClient
23
23
  @outer_indices << index
24
24
  end
25
25
 
26
- def get_inner_index(outer_index)
27
- @outer_indices&.find_index(outer_index)
28
- end
29
-
30
26
  def get_callee_method(inner_index)
31
27
  if @timeouts.is_a?(Array) && !@timeouts[inner_index].nil?
32
28
  :blocking_call_v
@@ -66,6 +62,7 @@ class RedisClient
66
62
  if result.is_a?(::RedisClient::Error)
67
63
  result._set_command(commands[index])
68
64
  result._set_config(config)
65
+ result._set_retry_attempt(@retry_attempt)
69
66
 
70
67
  if result.is_a?(::RedisClient::CommandError) && result.message.start_with?('MOVED', 'ASK')
71
68
  redirection_indices ||= []
@@ -61,17 +61,7 @@ class RedisClient
61
61
  end
62
62
 
63
63
  BUF_SIZE = Integer(ENV.fetch('REDIS_CLIENT_PUBSUB_BUF_SIZE', 1024))
64
- RECOVERY_BASE_INTERVAL = Float(ENV.fetch('REDIS_CLIENT_PUBSUB_RECOVERY_INTERVAL_SEC', 1.0))
65
- RECOVERY_MAX_INTERVAL = Float(ENV.fetch('REDIS_CLIENT_PUBSUB_RECOVERY_MAX_INTERVAL_SEC', 30.0))
66
- RECOVERY_MAX_ATTEMPTS = Integer(ENV.fetch('REDIS_CLIENT_PUBSUB_RECOVERY_MAX_ATTEMPTS', 10))
67
- SUBSCRIBE_COMMANDS = %w[subscribe psubscribe ssubscribe].freeze
68
- UNSUBSCRIBE_TO_SUBSCRIBE = {
69
- 'unsubscribe' => 'subscribe',
70
- 'punsubscribe' => 'psubscribe',
71
- 'sunsubscribe' => 'ssubscribe'
72
- }.freeze
73
- private_constant :BUF_SIZE, :RECOVERY_BASE_INTERVAL, :RECOVERY_MAX_INTERVAL, :RECOVERY_MAX_ATTEMPTS,
74
- :SUBSCRIBE_COMMANDS, :UNSUBSCRIBE_TO_SUBSCRIBE
64
+ private_constant :BUF_SIZE
75
65
 
76
66
  def initialize(router, command_builder)
77
67
  @router = router
@@ -84,14 +74,14 @@ class RedisClient
84
74
  def call(*args, **kwargs)
85
75
  command = @command_builder.generate(args, kwargs)
86
76
  _call(command)
87
- remember(command)
77
+ remember_subscription(command)
88
78
  nil
89
79
  end
90
80
 
91
81
  def call_v(command)
92
82
  command = @command_builder.generate(command)
93
83
  _call(command)
94
- remember(command)
84
+ remember_subscription(command)
95
85
  nil
96
86
  end
97
87
 
@@ -128,35 +118,6 @@ class RedisClient
128
118
 
129
119
  private
130
120
 
131
- def remember(command)
132
- cmd = command.first.to_s.downcase
133
- if SUBSCRIBE_COMMANDS.include?(cmd)
134
- @commands << command
135
- elsif (subscribe_cmd = UNSUBSCRIBE_TO_SUBSCRIBE[cmd])
136
- forget_subscriptions(subscribe_cmd, command[1..])
137
- else
138
- @commands << command
139
- end
140
- end
141
-
142
- def forget_subscriptions(subscribe_cmd, channels)
143
- if channels.nil? || channels.empty?
144
- @commands.reject! { |c| c.first.to_s.casecmp(subscribe_cmd).zero? }
145
- else
146
- @commands.reject! { |c| prune_entry(c, subscribe_cmd, channels) }
147
- end
148
- end
149
-
150
- def prune_entry(entry, subscribe_cmd, channels)
151
- return false unless entry.first.to_s.casecmp(subscribe_cmd).zero?
152
-
153
- remaining = entry[1..] - channels
154
- return true if remaining.empty?
155
-
156
- entry.replace([entry.first, *remaining])
157
- false
158
- end
159
-
160
121
  def _call(command) # rubocop:disable Metrics/AbcSize
161
122
  if command.first.casecmp('subscribe').zero?
162
123
  call_to_single_state(command)
@@ -227,14 +188,44 @@ class RedisClient
227
188
  break
228
189
  rescue ::RedisClient::ConnectionError, ::RedisClient::Cluster::NodeMightBeDown
229
190
  attempt += 1
230
- raise if attempt >= RECOVERY_MAX_ATTEMPTS
191
+ raise if attempt >= 10
231
192
 
232
193
  sleep recovery_interval(attempt)
233
194
  end
234
195
  end
235
196
 
236
197
  def recovery_interval(attempt)
237
- [RECOVERY_BASE_INTERVAL * (2**(attempt - 1)), RECOVERY_MAX_INTERVAL].min
198
+ [1.0 * (2**(attempt - 1)), 30.0].min
199
+ end
200
+
201
+ def remember_subscription(command) # rubocop:disable Metrics/AbcSize
202
+ if command.first.casecmp('subscribe').zero?
203
+ @commands << command
204
+ elsif command.first.casecmp('psubscribe').zero?
205
+ @commands << command
206
+ elsif command.first.casecmp('ssubscribe').zero?
207
+ @commands << command
208
+ elsif command.first.casecmp('unsubscribe').zero?
209
+ forget_subscriptions('subscribe', command[1, command.size])
210
+ elsif command.first.casecmp('punsubscribe').zero?
211
+ forget_subscriptions('psubscribe', command[1, command.size])
212
+ elsif command.first.casecmp('sunsubscribe').zero?
213
+ forget_subscriptions('ssubscribe', command[1, command.size])
214
+ end
215
+ end
216
+
217
+ def forget_subscriptions(subscribe_cmd, channels)
218
+ @commands.map! do |command|
219
+ next command unless command.first.casecmp(subscribe_cmd).zero?
220
+ next if channels.nil? || channels.empty?
221
+
222
+ remaining = command[1, command.size] - channels
223
+ next if remaining.empty?
224
+
225
+ [command.first, *remaining]
226
+ end
227
+
228
+ @commands.compact!
238
229
  end
239
230
  end
240
231
  end
@@ -167,19 +167,20 @@ class RedisClient
167
167
  raise unless ::RedisClient::Cluster::ErrorIdentification.client_owns_error?(e, node)
168
168
 
169
169
  renew_cluster_state
170
- retry_count -= 1
170
+ raise if command.nil? || command.empty?
171
171
 
172
- if retry_count >= 0
173
- # Find the node to use for this command - if this fails for some reason, though, re-use
174
- # the old node.
175
- begin
176
- node = find_node(find_node_key(command)) if command
177
- rescue StandardError # rubocop:disable Lint/SuppressedException
178
- end
179
- retry
172
+ retry_count -= 1
173
+ raise if retry_count < 0
174
+
175
+ # Find the node to use for this command - if this fails for some reason, though, re-use
176
+ # the old node.
177
+ begin
178
+ node = find_node(find_node_key(command))
179
+ rescue StandardError
180
+ raise e
180
181
  end
181
182
 
182
- raise
183
+ retry
183
184
  end
184
185
 
185
186
  def scan(command, seed: nil) # rubocop:disable Metrics/AbcSize
@@ -227,7 +228,7 @@ class RedisClient
227
228
  def find_node_key_by_key(key, seed: nil, primary: false)
228
229
  if key && !key.empty?
229
230
  slot = ::RedisClient::Cluster::KeySlotConverter.convert(key)
230
- node_key = primary ? @node.find_node_key_of_primary(slot) : @node.find_node_key_of_replica(slot)
231
+ node_key = primary ? @node.find_node_key_of_primary(slot) : @node.find_node_key_of_replica(slot, seed: seed)
231
232
  if node_key.nil?
232
233
  renew_cluster_state
233
234
  raise ::RedisClient::Cluster::NodeMightBeDown.new.with_config(@config)
@@ -171,7 +171,7 @@ class RedisClient
171
171
  send_transaction(node, redirect: redirect - 1)
172
172
  elsif err.message.start_with?('ASK')
173
173
  node = @router.assign_asking_node(err.message)
174
- try_asking(node) ? send_transaction(node, redirect: redirect - 1) : err
174
+ try_asking(node) ? send_transaction(node, redirect: redirect - 1) : raise(err)
175
175
  elsif err.message.start_with?('CLUSTERDOWN')
176
176
  @router.renew_cluster_state if @watching_slot.nil?
177
177
  raise err
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.16.4
4
+ version: 0.16.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taishi Kasuga
@@ -74,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  requirements: []
77
- rubygems_version: 4.0.6
77
+ rubygems_version: 4.0.10
78
78
  specification_version: 4
79
79
  summary: Redis cluster-aware client for Ruby
80
80
  test_files: []