redis-cluster-client 0.7.8 → 0.7.9
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5aa02a0e3934e8246e948260f2a4457b324de2377e7ec2e00fe9bf03a52f5ee4
|
4
|
+
data.tar.gz: 9f97a22af58eb64c64a6b73a79c2947bad06318e17bca235a5aa59fae35aad1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e8fcf1be08ba5c2582ad112455b02815410a81834b55bfc0035e0971556ff7b443e60a48a4cc2f5c94fdd81d09a5d03d3c261b4e0afb13ac9f38da5d4f0ab64
|
7
|
+
data.tar.gz: 77f17d9e003384f34e5719f0e84f70c8a04f7de196974fc5af830e4825827b01d7df94b4eb887d4a1a4a77f43caa989cfdcbb1e874d807503bf9ef254ea95a0d
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'redis_client'
|
4
|
-
require 'redis_client/cluster/key_slot_converter'
|
5
4
|
require 'redis_client/cluster/transaction'
|
6
5
|
|
7
6
|
class RedisClient
|
@@ -12,15 +11,14 @@ class RedisClient
|
|
12
11
|
end
|
13
12
|
|
14
13
|
def watch(keys)
|
15
|
-
|
16
|
-
|
17
|
-
cnt = 0 # We assume redirects occurred when incrementing it.
|
14
|
+
slot = find_slot(keys)
|
15
|
+
raise ::RedisClient::Cluster::Transaction::ConsistencyError, "unsafe watch: #{keys.join(' ')}" if slot.nil?
|
18
16
|
|
17
|
+
node = @router.find_primary_node_by_slot(slot)
|
19
18
|
@router.handle_redirection(node, retry_count: 1) do |nd|
|
20
|
-
cnt += 1
|
21
19
|
nd.with do |c|
|
22
20
|
c.call('WATCH', *keys)
|
23
|
-
reply = yield(c,
|
21
|
+
reply = yield(c, slot)
|
24
22
|
c.call('UNWATCH')
|
25
23
|
reply
|
26
24
|
end
|
@@ -29,29 +27,14 @@ class RedisClient
|
|
29
27
|
|
30
28
|
private
|
31
29
|
|
32
|
-
def
|
33
|
-
return if
|
30
|
+
def find_slot(keys)
|
31
|
+
return if keys.empty?
|
32
|
+
return if keys.any? { |k| k.nil? || k.empty? }
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
def safe?(keys)
|
39
|
-
return false if keys.empty?
|
40
|
-
|
41
|
-
slots = keys.map do |k|
|
42
|
-
return false if k.nil? || k.empty?
|
43
|
-
|
44
|
-
::RedisClient::Cluster::KeySlotConverter.convert(k)
|
45
|
-
end
|
46
|
-
|
47
|
-
slots.uniq.size == 1
|
48
|
-
end
|
49
|
-
|
50
|
-
def find_node(keys)
|
51
|
-
node_key = @router.find_primary_node_key(['WATCH', *keys])
|
52
|
-
return @router.find_node(node_key) unless node_key.nil?
|
34
|
+
slots = keys.map { |k| @router.find_slot_by_key(k) }
|
35
|
+
return if slots.uniq.size != 1
|
53
36
|
|
54
|
-
|
37
|
+
slots.first
|
55
38
|
end
|
56
39
|
end
|
57
40
|
end
|
@@ -179,6 +179,16 @@ class RedisClient
|
|
179
179
|
find_node_key_by_key(key, primary: true)
|
180
180
|
end
|
181
181
|
|
182
|
+
def find_slot(command)
|
183
|
+
find_slot_by_key(@command.extract_first_key(command))
|
184
|
+
end
|
185
|
+
|
186
|
+
def find_slot_by_key(key)
|
187
|
+
return if key.empty?
|
188
|
+
|
189
|
+
::RedisClient::Cluster::KeySlotConverter.convert(key)
|
190
|
+
end
|
191
|
+
|
182
192
|
def find_node(node_key, retry_count: 3)
|
183
193
|
@node.find_by(node_key)
|
184
194
|
rescue ::RedisClient::Cluster::Node::ReloadNeeded
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'redis_client'
|
4
4
|
require 'redis_client/cluster/pipeline'
|
5
|
-
require 'redis_client/cluster/node_key'
|
6
5
|
|
7
6
|
class RedisClient
|
8
7
|
class Cluster
|
@@ -10,7 +9,7 @@ class RedisClient
|
|
10
9
|
ConsistencyError = Class.new(::RedisClient::Error)
|
11
10
|
MAX_REDIRECTION = 2
|
12
11
|
|
13
|
-
def initialize(router, command_builder, node: nil,
|
12
|
+
def initialize(router, command_builder, node: nil, slot: nil)
|
14
13
|
@router = router
|
15
14
|
@command_builder = command_builder
|
16
15
|
@retryable = true
|
@@ -18,7 +17,7 @@ class RedisClient
|
|
18
17
|
@pending_commands = []
|
19
18
|
@node = node
|
20
19
|
prepare_tx unless @node.nil?
|
21
|
-
@
|
20
|
+
@watching_slot = slot
|
22
21
|
end
|
23
22
|
|
24
23
|
def call(*command, **kwargs, &block)
|
@@ -111,7 +110,7 @@ class RedisClient
|
|
111
110
|
client.middlewares.call_pipelined(commands, client.config) do
|
112
111
|
connection.call_pipelined(commands, nil)
|
113
112
|
rescue ::RedisClient::CommandError => e
|
114
|
-
return handle_command_error!(
|
113
|
+
return handle_command_error!(commands, e, redirect: redirect) unless redirect.zero?
|
115
114
|
|
116
115
|
raise
|
117
116
|
end
|
@@ -140,15 +139,15 @@ class RedisClient
|
|
140
139
|
results
|
141
140
|
end
|
142
141
|
|
143
|
-
def handle_command_error!(
|
142
|
+
def handle_command_error!(commands, err, redirect:) # rubocop:disable Metrics/AbcSize
|
144
143
|
if err.message.start_with?('CROSSSLOT')
|
145
144
|
raise ConsistencyError, "#{err.message}: #{err.command}"
|
146
145
|
elsif err.message.start_with?('MOVED')
|
147
|
-
|
146
|
+
ensure_the_same_slot!(commands)
|
148
147
|
node = @router.assign_redirection_node(err.message)
|
149
148
|
send_transaction(node, redirect: redirect - 1)
|
150
149
|
elsif err.message.start_with?('ASK')
|
151
|
-
|
150
|
+
ensure_the_same_slot!(commands)
|
152
151
|
node = @router.assign_asking_node(err.message)
|
153
152
|
try_asking(node) ? send_transaction(node, redirect: redirect - 1) : err
|
154
153
|
else
|
@@ -156,12 +155,10 @@ class RedisClient
|
|
156
155
|
end
|
157
156
|
end
|
158
157
|
|
159
|
-
def
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
return if !@resharding_state && node_keys.size == 1 && node_keys.first == expected_node_key
|
164
|
-
return if @resharding_state && node_keys.size == 1
|
158
|
+
def ensure_the_same_slot!(commands)
|
159
|
+
slots = commands.map { |command| @router.find_slot(command) }.compact.uniq
|
160
|
+
return if slots.size == 1 && @watching_slot.nil?
|
161
|
+
return if slots.size == 1 && @watching_slot == slots.first
|
165
162
|
|
166
163
|
raise(ConsistencyError, "the transaction should be executed to a slot in a node: #{commands}")
|
167
164
|
end
|
data/lib/redis_client/cluster.rb
CHANGED
@@ -98,9 +98,9 @@ class RedisClient
|
|
98
98
|
return transaction.execute
|
99
99
|
end
|
100
100
|
|
101
|
-
::RedisClient::Cluster::OptimisticLocking.new(@router).watch(watch) do |c,
|
101
|
+
::RedisClient::Cluster::OptimisticLocking.new(@router).watch(watch) do |c, slot|
|
102
102
|
transaction = ::RedisClient::Cluster::Transaction.new(
|
103
|
-
@router, @command_builder, node: c,
|
103
|
+
@router, @command_builder, node: c, slot: slot
|
104
104
|
)
|
105
105
|
yield transaction
|
106
106
|
transaction.execute
|