redis-cluster-client 0.7.3 → 0.7.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: be05e560aaf9384463913ded42ed7af2be53c9439a80529bbfabc96b523d077e
4
- data.tar.gz: cf0b7ef156f19f240107c29bbb803949f9b7034052e0e9bffb668923bcf62322
3
+ metadata.gz: 8f07e3f65dcf4125b72089921a28fc2048d98bc95763d7ec2a5f0702e3ba542d
4
+ data.tar.gz: a69bdc239562da7c18b6b8eedfbb16b51879416f0093eb472b35f212080ae29e
5
5
  SHA512:
6
- metadata.gz: a3bb611795108e0870668c86470a9eedce8a84bc7e80d6df974a5a35bde64de1c74fdd031969299c42f1861404b73cb02506bf83dc4ea82264548b058641c6fc
7
- data.tar.gz: 7ec956a5e98ed22bf9a7dd7428d3b4e55694a824c5d6b3acba558ac40855014eebcf3ddd286863d7393ca3356d97b1fa25c42edec8533d42750401dd93101de0
6
+ metadata.gz: 7afe4938ca64ebbcd4607144b0fb634a26c3ba99a463ded614da7f7b2a52e59a607c27949bcf4e746ce7ed31d71e3d37d204b054ffef6c8b35ed8f72a83f632e
7
+ data.tar.gz: 876cc376f32d4c3d6d4b3c8c413e360fd91260bf173d80a90202428b7cef6923057da54df490111950cc278de49026a3f7726483d71bb24fd14e897e6c6f3f03
@@ -21,11 +21,14 @@ class RedisClient
21
21
  )
22
22
 
23
23
  class << self
24
- def load(nodes)
24
+ def load(nodes, slow_command_timeout: -1)
25
25
  cmd = errors = nil
26
26
 
27
27
  nodes&.each do |node|
28
+ regular_timeout = node.read_timeout
29
+ node.read_timeout = slow_command_timeout > 0.0 ? slow_command_timeout : regular_timeout
28
30
  reply = node.call('COMMAND')
31
+ node.read_timeout = regular_timeout
29
32
  commands = parse_command_reply(reply)
30
33
  cmd = ::RedisClient::Cluster::Command.new(commands)
31
34
  break
@@ -13,11 +13,15 @@ class RedisClient
13
13
  class Node
14
14
  include Enumerable
15
15
 
16
+ # It affects to strike a balance between load and stability in initialization or changed states.
17
+ MAX_STARTUP_SAMPLE = Integer(ENV.fetch('REDIS_CLIENT_MAX_STARTUP_SAMPLE', 3))
18
+
19
+ # less memory consumption, but slow
20
+ USE_CHAR_ARRAY_SLOT = Integer(ENV.fetch('REDIS_CLIENT_USE_CHAR_ARRAY_SLOT', 1)) == 1
21
+
16
22
  SLOT_SIZE = 16_384
17
23
  MIN_SLOT = 0
18
24
  MAX_SLOT = SLOT_SIZE - 1
19
- MAX_STARTUP_SAMPLE = Integer(ENV.fetch('REDIS_CLIENT_MAX_STARTUP_SAMPLE', 3))
20
- USE_CHAR_ARRAY_SLOT = Integer(ENV.fetch('REDIS_CLIENT_USE_CHAR_ARRAY_SLOT', 1)) == 1 # less memory consumption, but slow
21
25
  IGNORE_GENERIC_CONFIG_KEYS = %i[url host port path].freeze
22
26
  DEAD_FLAGS = %w[fail? fail handshake noaddr noflags].freeze
23
27
  ROLE_FLAGS = %w[master slave].freeze
@@ -89,7 +93,7 @@ class RedisClient
89
93
  end
90
94
 
91
95
  class << self
92
- def load_info(options, concurrent_worker, **kwargs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
96
+ def load_info(options, concurrent_worker, slow_command_timeout: -1, **kwargs) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
93
97
  raise ::RedisClient::Cluster::InitialSetupError, [] if options.nil? || options.empty?
94
98
 
95
99
  startup_size = options.size > MAX_STARTUP_SAMPLE ? MAX_STARTUP_SAMPLE : options.size
@@ -99,7 +103,10 @@ class RedisClient
99
103
 
100
104
  startup_nodes.each_with_index do |raw_client, i|
101
105
  work_group.push(i, raw_client) do |client|
106
+ regular_timeout = client.read_timeout
107
+ client.read_timeout = slow_command_timeout > 0.0 ? slow_command_timeout : regular_timeout
102
108
  reply = client.call('CLUSTER', 'NODES')
109
+ client.read_timeout = regular_timeout
103
110
  parse_cluster_node_reply(reply)
104
111
  rescue StandardError => e
105
112
  e
@@ -209,10 +216,6 @@ class RedisClient
209
216
  @topology.clients.each_value(&block)
210
217
  end
211
218
 
212
- def shuffled_nodes
213
- @topology.clients.values.shuffle
214
- end
215
-
216
219
  def sample
217
220
  @topology.clients.values.sample
218
221
  end
@@ -252,6 +255,10 @@ class RedisClient
252
255
  @topology.clients_for_scanning(seed: seed).values.sort_by { |c| "#{c.config.host}-#{c.config.port}" }
253
256
  end
254
257
 
258
+ def replica_clients
259
+ @topology.replica_clients.values
260
+ end
261
+
255
262
  def find_node_key_of_primary(slot)
256
263
  return if slot.nil?
257
264
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'redis_client'
4
+ require 'redis_client/cluster/normalized_cmd_name'
4
5
 
5
6
  class RedisClient
6
7
  class Cluster
@@ -18,11 +18,13 @@ class RedisClient
18
18
 
19
19
  def initialize(config, concurrent_worker, pool: nil, **kwargs)
20
20
  @config = config.dup
21
+ @original_config = config.dup if config.connect_with_original_config
22
+ @connect_with_original_config = config.connect_with_original_config
21
23
  @concurrent_worker = concurrent_worker
22
24
  @pool = pool
23
25
  @client_kwargs = kwargs
24
26
  @node = fetch_cluster_info(@config, @concurrent_worker, pool: @pool, **@client_kwargs)
25
- @command = ::RedisClient::Cluster::Command.load(@node.shuffled_nodes)
27
+ @command = ::RedisClient::Cluster::Command.load(@node.replica_clients.shuffle, slow_command_timeout: config.slow_command_timeout)
26
28
  @mutex = Mutex.new
27
29
  @command_builder = @config.command_builder
28
30
  end
@@ -305,7 +307,7 @@ class RedisClient
305
307
  end
306
308
 
307
309
  def fetch_cluster_info(config, concurrent_worker, pool: nil, **kwargs)
308
- node_info_list = ::RedisClient::Cluster::Node.load_info(config.per_node_key, concurrent_worker, **kwargs)
310
+ node_info_list = ::RedisClient::Cluster::Node.load_info(config.per_node_key, concurrent_worker, slow_command_timeout: config.slow_command_timeout, **kwargs)
309
311
  node_addrs = node_info_list.map { |i| ::RedisClient::Cluster::NodeKey.hashify(i.node_key) }
310
312
  config.update_node(node_addrs)
311
313
  ::RedisClient::Cluster::Node.new(
@@ -329,6 +331,7 @@ class RedisClient
329
331
  # ignore
330
332
  end
331
333
 
334
+ @config = @original_config.dup if @connect_with_original_config
332
335
  @node = fetch_cluster_info(@config, @concurrent_worker, pool: @pool, **@client_kwargs)
333
336
  end
334
337
  end
@@ -18,18 +18,22 @@ class RedisClient
18
18
  MERGE_CONFIG_KEYS = %i[ssl username password].freeze
19
19
  IGNORE_GENERIC_CONFIG_KEYS = %i[url host port path].freeze
20
20
  MAX_WORKERS = Integer(ENV.fetch('REDIS_CLIENT_MAX_THREADS', 5))
21
+ # It's used with slow queries of fetching meta data like CLUSTER NODES, COMMAND and so on.
22
+ SLOW_COMMAND_TIMEOUT = Float(ENV.fetch('REDIS_CLIENT_SLOW_COMMAND_TIMEOUT', -1))
21
23
 
22
24
  InvalidClientConfigError = Class.new(::RedisClient::Error)
23
25
 
24
- attr_reader :command_builder, :client_config, :replica_affinity
26
+ attr_reader :command_builder, :client_config, :replica_affinity, :slow_command_timeout, :connect_with_original_config
25
27
 
26
- def initialize(
28
+ def initialize( # rubocop:disable Metrics/AbcSize
27
29
  nodes: DEFAULT_NODES,
28
30
  replica: false,
29
31
  replica_affinity: :random,
30
32
  fixed_hostname: '',
31
33
  concurrency: nil,
34
+ connect_with_original_config: false,
32
35
  client_implementation: ::RedisClient::Cluster, # for redis gem
36
+ slow_command_timeout: SLOW_COMMAND_TIMEOUT,
33
37
  **client_config
34
38
  )
35
39
 
@@ -41,7 +45,9 @@ class RedisClient
41
45
  @command_builder = client_config.fetch(:command_builder, ::RedisClient::CommandBuilder)
42
46
  @client_config = merge_generic_config(client_config, @node_configs)
43
47
  @concurrency = merge_concurrency_option(concurrency)
48
+ @connect_with_original_config = connect_with_original_config
44
49
  @client_implementation = client_implementation
50
+ @slow_command_timeout = slow_command_timeout
45
51
  @mutex = Mutex.new
46
52
  end
47
53
 
@@ -52,7 +58,9 @@ class RedisClient
52
58
  replica_affinity: @replica_affinity,
53
59
  fixed_hostname: @fixed_hostname,
54
60
  concurrency: @concurrency,
61
+ connect_with_original_config: @connect_with_original_config,
55
62
  client_implementation: @client_implementation,
63
+ slow_command_timeout: @slow_command_timeout,
56
64
  **@client_config
57
65
  )
58
66
  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.7.3
4
+ version: 0.7.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: 2023-10-02 00:00:00.000000000 Z
11
+ date: 2023-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client