From 180900500ad11e7af9361b3cf891e6dce10ae72c Mon Sep 17 00:00:00 2001 From: Taishi Kasuga Date: Tue, 20 Feb 2024 11:36:44 +0900 Subject: [PATCH 1/2] fix: add dedicated implementation for watch command, it may be used by redis-rb --- lib/redis_client/cluster/router.rb | 14 ++++++++++++++ test/redis_client/test_cluster.rb | 15 +++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib/redis_client/cluster/router.rb b/lib/redis_client/cluster/router.rb index a73e90b..c51f4a5 100644 --- a/lib/redis_client/cluster/router.rb +++ b/lib/redis_client/cluster/router.rb @@ -8,6 +8,8 @@ require 'redis_client/cluster/node' require 'redis_client/cluster/node_key' require 'redis_client/cluster/normalized_cmd_name' +require 'redis_client/cluster/transaction' +require 'redis_client/cluster/optimistic_locking' class RedisClient class Cluster @@ -44,6 +46,7 @@ def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSi when 'memory' then send_memory_command(method, command, args, &block) when 'script' then send_script_command(method, command, args, &block) when 'pubsub' then send_pubsub_command(method, command, args, &block) + when 'watch' then send_watch_command(args, &block) when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save' @node.call_all(method, command, args).first.then(&TSF.call(block)) when 'flushall', 'flushdb' @@ -308,6 +311,17 @@ def send_pubsub_command(method, command, args, &block) # rubocop:disable Metrics end end + # for redis-rb + def send_watch_command(args) + ::RedisClient::Cluster::OptimisticLocking.new(self).watch(args) do |c, slot| + transaction = ::RedisClient::Cluster::Transaction.new( + self, @command_builder, node: c, slot: slot + ) + yield transaction + transaction.execute + end + end + def update_cluster_info! @node.reload! end diff --git a/test/redis_client/test_cluster.rb b/test/redis_client/test_cluster.rb index 6b1a580..84b77ca 100644 --- a/test/redis_client/test_cluster.rb +++ b/test/redis_client/test_cluster.rb @@ -363,6 +363,21 @@ def test_transaction_in_race_condition assert_equal(%w[3 4], @client.call('MGET', '{key}1', '{key}2')) end + # for redis-rb + def test_transaction_with_standalone_watch_command + @client.call('MSET', '{key}1', '0', '{key}2', '0') + + got = @client.call('WATCH', '{key}1', '{key}2') do |tx| + tx.call('ECHO', 'START') + tx.call('SET', '{key}1', '1') + tx.call('SET', '{key}2', '2') + tx.call('ECHO', 'FINISH') + end + + assert_equal(%w[START OK OK FINISH], got) + assert_equal(%w[1 2], @client.call('MGET', '{key}1', '{key}2')) + end + def test_pubsub_without_subscription pubsub = @client.pubsub assert_nil(pubsub.next_event(0.01)) From a9111d258b0d52e96e6d01669dd03a212013db73 Mon Sep 17 00:00:00 2001 From: Taishi Kasuga Date: Tue, 20 Feb 2024 11:43:54 +0900 Subject: [PATCH 2/2] fix --- lib/redis_client/cluster/router.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/redis_client/cluster/router.rb b/lib/redis_client/cluster/router.rb index c51f4a5..45fd13c 100644 --- a/lib/redis_client/cluster/router.rb +++ b/lib/redis_client/cluster/router.rb @@ -46,7 +46,7 @@ def send_command(method, command, *args, &block) # rubocop:disable Metrics/AbcSi when 'memory' then send_memory_command(method, command, args, &block) when 'script' then send_script_command(method, command, args, &block) when 'pubsub' then send_pubsub_command(method, command, args, &block) - when 'watch' then send_watch_command(args, &block) + when 'watch' then send_watch_command(command, &block) when 'acl', 'auth', 'bgrewriteaof', 'bgsave', 'quit', 'save' @node.call_all(method, command, args).first.then(&TSF.call(block)) when 'flushall', 'flushdb' @@ -312,8 +312,8 @@ def send_pubsub_command(method, command, args, &block) # rubocop:disable Metrics end # for redis-rb - def send_watch_command(args) - ::RedisClient::Cluster::OptimisticLocking.new(self).watch(args) do |c, slot| + def send_watch_command(command) + ::RedisClient::Cluster::OptimisticLocking.new(self).watch(command[1..]) do |c, slot| transaction = ::RedisClient::Cluster::Transaction.new( self, @command_builder, node: c, slot: slot )