@@ -54,6 +54,32 @@ def test_forking_with_pipelining
5454 MAX_THREADS . times { |i | assert_equal ( WANT , @client . call ( 'GET' , "key#{ i } " ) ) }
5555 end
5656
57+ def test_forking_with_transaction
58+ skip ( "fork is not available on #{ RUBY_ENGINE } " ) if %w[ jruby truffleruby ] . include? ( RUBY_ENGINE )
59+
60+ @client . call ( 'SET' , '{key}1' , WANT )
61+
62+ pids = Array . new ( MAX_THREADS ) do
63+ Process . fork do
64+ @client . multi ( watch : %w[ {key}1 ] ) do |tx |
65+ ATTEMPTS . times do
66+ MAX_THREADS . times do
67+ tx . call ( 'INCR' , '{key}1' )
68+ tx . call ( 'DECR' , '{key}1' )
69+ end
70+ end
71+ end
72+ end
73+ end
74+
75+ pids . each do |pid |
76+ _ , status = Process . waitpid2 ( pid )
77+ assert_predicate ( status , :success? )
78+ end
79+
80+ assert_equal ( WANT , @client . call ( 'GET' , '{key}1' ) )
81+ end
82+
5783 def test_threading
5884 threads = Array . new ( MAX_THREADS ) do
5985 Thread . new do
@@ -84,6 +110,28 @@ def test_threading_with_pipelining
84110 MAX_THREADS . times { |i | assert_equal ( WANT , @client . call ( 'GET' , "key#{ i } " ) ) }
85111 end
86112
113+ def test_threading_with_transaction
114+ @client . call ( 'SET' , '{key}1' , WANT )
115+
116+ threads = Array . new ( MAX_THREADS ) do
117+ Thread . new do
118+ @client . multi ( watch : %w[ {key}1 ] ) do |tx |
119+ ATTEMPTS . times do
120+ MAX_THREADS . times do
121+ tx . call ( 'INCR' , '{key}1' )
122+ tx . call ( 'DECR' , '{key}1' )
123+ end
124+ end
125+ end
126+ rescue StandardError => e
127+ e
128+ end
129+ end
130+
131+ threads . each { |t | refute_instance_of ( StandardError , t . value ) }
132+ assert_equal ( WANT , @client . call ( 'GET' , '{key}1' ) )
133+ end
134+
87135 private
88136
89137 def new_test_client
0 commit comments