Skip to content

Commit 41625e6

Browse files
authored
fix: add a dedicated implementation for the watch command, it may be used by the redis gem (#333)
1 parent 02776d7 commit 41625e6

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

lib/redis_client/cluster/router.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
require 'redis_client/cluster/node'
99
require 'redis_client/cluster/node_key'
1010
require 'redis_client/cluster/normalized_cmd_name'
11+
require 'redis_client/cluster/transaction'
12+
require 'redis_client/cluster/optimistic_locking'
1113

1214
class RedisClient
1315
class Cluster
@@ -44,6 +46,7 @@ def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSi
4446
when 'memory' then send_memory_command(method, command, args, &block)
4547
when 'script' then send_script_command(method, command, args, &block)
4648
when 'pubsub' then send_pubsub_command(method, command, args, &block)
49+
when 'watch' then send_watch_command(command, &block)
4750
when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save'
4851
@node.call_all(method, command, args).first.then(&TSF.call(block))
4952
when 'flushall', 'flushdb'
@@ -308,6 +311,17 @@ def send_pubsub_command(method, command, args, &block) # rubocop:disable Metrics
308311
end
309312
end
310313

314+
# for redis-rb
315+
def send_watch_command(command)
316+
::RedisClient::Cluster::OptimisticLocking.new(self).watch(command[1..]) do |c, slot|
317+
transaction = ::RedisClient::Cluster::Transaction.new(
318+
self, @command_builder, node: c, slot: slot
319+
)
320+
yield transaction
321+
transaction.execute
322+
end
323+
end
324+
311325
def update_cluster_info!
312326
@node.reload!
313327
end

test/redis_client/test_cluster.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,21 @@ def test_transaction_in_race_condition
363363
assert_equal(%w[3 4], @client.call('MGET', '{key}1', '{key}2'))
364364
end
365365

366+
# for redis-rb
367+
def test_transaction_with_standalone_watch_command
368+
@client.call('MSET', '{key}1', '0', '{key}2', '0')
369+
370+
got = @client.call('WATCH', '{key}1', '{key}2') do |tx|
371+
tx.call('ECHO', 'START')
372+
tx.call('SET', '{key}1', '1')
373+
tx.call('SET', '{key}2', '2')
374+
tx.call('ECHO', 'FINISH')
375+
end
376+
377+
assert_equal(%w[START OK OK FINISH], got)
378+
assert_equal(%w[1 2], @client.call('MGET', '{key}1', '{key}2'))
379+
end
380+
366381
def test_pubsub_without_subscription
367382
pubsub = @client.pubsub
368383
assert_nil(pubsub.next_event(0.01))

0 commit comments

Comments
 (0)