Class: SolidRedis::ClusterClient
- Inherits:
-
Object
- Object
- SolidRedis::ClusterClient
- Defined in:
- lib/solid_redis/cluster_client.rb
Overview
Routes commands to the cluster node owning their key slot and follows MOVED/ASK redirections. Holds one Client per node; all of them belong to the Ractor that created this object.
Constant Summary collapse
- REDIRECTION =
/\A(MOVED|ASK) (\d+) (\S+):(\d+)\z/- RETRY_DELAY =
0.05
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
- #blocking_call(timeout, *command) ⇒ Object
- #blocking_call_v(timeout, command) ⇒ Object
- #call(*command) ⇒ Object
- #call_v(command) ⇒ Object
- #close ⇒ Object
- #connected? ⇒ Boolean
-
#initialize(config, name: nil) ⇒ ClusterClient
constructor
A new instance of ClusterClient.
-
#pipelined(exception: true) {|pipeline| ... } ⇒ Object
Groups commands by node, runs one pipeline per node and restores the original order.
- #server_url ⇒ Object
Constructor Details
#initialize(config, name: nil) ⇒ ClusterClient
Returns a new instance of ClusterClient.
13 14 15 16 17 |
# File 'lib/solid_redis/cluster_client.rb', line 13 def initialize(config, name: nil) @config = config @name = name @clients = {} end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
11 12 13 |
# File 'lib/solid_redis/cluster_client.rb', line 11 def config @config end |
Instance Method Details
#blocking_call(timeout, *command) ⇒ Object
27 28 29 |
# File 'lib/solid_redis/cluster_client.rb', line 27 def blocking_call(timeout, *command) blocking_call_v(timeout, command) end |
#blocking_call_v(timeout, command) ⇒ Object
31 32 33 |
# File 'lib/solid_redis/cluster_client.rb', line 31 def blocking_call_v(timeout, command) route(command, retry_connection: false) { |client| client.blocking_call_v(timeout, command) } end |
#call(*command) ⇒ Object
19 20 21 |
# File 'lib/solid_redis/cluster_client.rb', line 19 def call(*command) call_v(command) end |
#call_v(command) ⇒ Object
23 24 25 |
# File 'lib/solid_redis/cluster_client.rb', line 23 def call_v(command) route(command) { |client| client.call_v(command) } end |
#close ⇒ Object
72 73 74 75 76 77 |
# File 'lib/solid_redis/cluster_client.rb', line 72 def close clients = @clients.values @clients = {} clients.each(&:close) self end |
#connected? ⇒ Boolean
68 69 70 |
# File 'lib/solid_redis/cluster_client.rb', line 68 def connected? @clients.values.any?(&:connected?) end |
#pipelined(exception: true) {|pipeline| ... } ⇒ Object
Groups commands by node, runs one pipeline per node and restores the original order. Redirected commands are replayed individually.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/solid_redis/cluster_client.rb', line 37 def pipelined(exception: true) pipeline = Client::Pipeline.new yield pipeline commands = pipeline.commands return [] if commands.empty? results = Array.new(commands.length) commands.each_with_index.group_by { |command, _| node_for(command) }.each do |node, group| replies = client_for(node).pipelined(exception: false) do |batch| group.each { |command, _| batch.call_v(command) } end group.each_with_index { |(_, index), position| results[index] = replies[position] } end results.each_with_index do |result, index| next unless result.is_a?(CommandError) && result..match?(REDIRECTION) results[index] = begin call_v(commands[index]) rescue CommandError => error error end end if exception && (error = results.find { |result| result.is_a?(CommandError) }) raise error end results end |
#server_url ⇒ Object
79 80 81 |
# File 'lib/solid_redis/cluster_client.rb', line 79 def server_url @clients.keys.join(",") end |