Skip to content

Commit 65ac655

Browse files
committed
Fix the watch command bugs for the cluster client
1 parent 7cc45e5 commit 65ac655

File tree

5 files changed

+49
-5
lines changed

5 files changed

+49
-5
lines changed

cluster/lib/redis/cluster.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ def cluster(subcommand, *args)
9696
send_command([:cluster, subcommand] + args, &block)
9797
end
9898

99+
def watch(*keys, &block)
100+
synchronize { |c| c.call_v([:watch] + keys, &block) }
101+
end
102+
99103
private
100104

101105
def initialize_client(options)

cluster/redis-clustering.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ Gem::Specification.new do |s|
4747
s.required_ruby_version = '>= 2.7.0'
4848

4949
s.add_runtime_dependency('redis', s.version)
50-
s.add_runtime_dependency('redis-cluster-client', '>= 0.7.0')
50+
s.add_runtime_dependency('redis-cluster-client', '>= 0.7.11')
5151
end

cluster/test/client_transactions_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,25 @@ def test_cluster_client_does_not_support_transaction_by_multiple_keys
4848
assert_nil(redis.get("key#{i}"))
4949
end
5050
end
51+
52+
def test_cluster_client_does_support_transaction_with_optimistic_locking
53+
redis.mset('{key}1', '1', '{key}2', '2')
54+
55+
another = Fiber.new do
56+
cli = build_another_client
57+
cli.mset('{key}1', '3', '{key}2', '4')
58+
cli.close
59+
Fiber.yield
60+
end
61+
62+
redis.watch('{key}1', '{key}2') do |tx|
63+
another.resume
64+
v1 = redis.get('{key}1')
65+
v2 = redis.get('{key}2')
66+
tx.call('SET', '{key}1', v2)
67+
tx.call('SET', '{key}2', v1)
68+
end
69+
70+
assert_equal %w[3 4], redis.mget('{key}1', '{key}2')
71+
end
5172
end

cluster/test/commands_on_transactions_test.rb

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,29 @@ def test_unwatch
3838
end
3939

4040
def test_watch
41-
assert_raises(Redis::CommandError, "CROSSSLOT Keys in request don't hash to the same slot") do
42-
redis.watch('key1', 'key2')
41+
assert_raises(Redis::Cluster::TransactionConsistencyError) do
42+
redis.watch('{key}1', '{key}2')
4343
end
4444

45-
assert_equal 'OK', redis.watch('{key}1', '{key}2')
45+
assert_raises(Redis::Cluster::TransactionConsistencyError) do
46+
redis.watch('key1', 'key2') do |tx|
47+
tx.call('SET', 'key1', '1')
48+
tx.call('SET', 'key2', '2')
49+
end
50+
end
51+
52+
assert_raises(Redis::Cluster::TransactionConsistencyError) do
53+
redis.watch('{hey}1', '{hey}2') do |tx|
54+
tx.call('SET', '{key}1', '1')
55+
tx.call('SET', '{key}2', '2')
56+
end
57+
end
58+
59+
redis.watch('{key}1', '{key}2') do |tx|
60+
tx.call('SET', '{key}1', '1')
61+
tx.call('SET', '{key}2', '2')
62+
end
63+
64+
assert_equal %w[1 2], redis.mget('{key}1', '{key}2')
4665
end
4766
end

test/helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def version
174174
def with_acl
175175
admin = _new_client
176176
admin.acl('SETUSER', 'johndoe', 'on',
177-
'+ping', '+select', '+command', '+cluster|slots', '+cluster|nodes',
177+
'+ping', '+select', '+command', '+cluster|slots', '+cluster|nodes', '+readonly',
178178
'>mysecret')
179179
yield('johndoe', 'mysecret')
180180
ensure

0 commit comments

Comments
 (0)