@@ -54,6 +54,32 @@ def test_forking_with_pipelining
54
54
MAX_THREADS . times { |i | assert_equal ( WANT , @client . call ( 'GET' , "key#{ i } " ) ) }
55
55
end
56
56
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
+
57
83
def test_threading
58
84
threads = Array . new ( MAX_THREADS ) do
59
85
Thread . new do
@@ -84,6 +110,28 @@ def test_threading_with_pipelining
84
110
MAX_THREADS . times { |i | assert_equal ( WANT , @client . call ( 'GET' , "key#{ i } " ) ) }
85
111
end
86
112
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
+
87
135
private
88
136
89
137
def new_test_client
0 commit comments