Skip to content

Commit 707b0fb

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

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
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/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: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,25 @@ 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('key1', 'key2') do |tx|
43+
tx.call('SET', 'key1', '1')
44+
tx.call('SET', 'key2', '2')
45+
end
4346
end
4447

45-
assert_equal 'OK', redis.watch('{key}1', '{key}2')
48+
assert_raises(Redis::Cluster::TransactionConsistencyError) do
49+
redis.watch('{hey}1', '{hey}2') do |tx|
50+
tx.call('SET', '{key}1', '1')
51+
tx.call('SET', '{key}2', '2')
52+
end
53+
end
54+
55+
redis.watch('{key}1', '{key}2') do |tx|
56+
tx.call('SET', '{key}1', '1')
57+
tx.call('SET', '{key}2', '2')
58+
end
59+
60+
assert_equal %w[1 2], redis.mget('{key}1', '{key}2')
4661
end
4762
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)