@@ -132,6 +132,84 @@ def test_threading_with_transaction
132132 assert_equal ( WANT , @client . call ( 'GET' , '{key}1' ) )
133133 end
134134
135+ def test_ractor
136+ skip ( 'Ractor is not available' ) unless Object . const_defined? ( :Ractor , false )
137+ skip ( "#{ RedisClient . default_driver } is not safe for Ractor" ) if RedisClient . default_driver != RedisClient ::RubyConnection
138+ skip ( 'OpenSSL gem has non-shareable objects' ) if TEST_REDIS_SSL
139+ skip ( 'test case may get stuck' ) if RUBY_ENGINE == 'ruby' && RUBY_ENGINE_VERSION . split ( '.' ) . take ( 2 ) . join ( '.' ) . to_f < 3.1
140+
141+ ractors = Array . new ( MAX_THREADS ) do |i |
142+ Ractor . new ( i ) do |i |
143+ c = ::RedisClient . cluster (
144+ nodes : TEST_NODE_URIS ,
145+ fixed_hostname : TEST_FIXED_HOSTNAME ,
146+ **TEST_GENERIC_OPTIONS
147+ ) . new_client
148+ c . call ( 'get' , "key#{ i } " )
149+ rescue StandardError => e
150+ e
151+ ensure
152+ c &.close
153+ end
154+ end
155+
156+ ractors . each { |r | assert_equal ( WANT , r . take ) }
157+ end
158+
159+ def test_ractor_with_pipelining
160+ skip ( 'Ractor is not available' ) unless Object . const_defined? ( :Ractor , false )
161+ skip ( "#{ RedisClient . default_driver } is not safe for Ractor" ) if RedisClient . default_driver != RedisClient ::RubyConnection
162+ skip ( 'OpenSSL gem has non-shareable objects' ) if TEST_REDIS_SSL
163+ skip ( 'test case may get stuck' ) if RUBY_ENGINE == 'ruby' && RUBY_ENGINE_VERSION . split ( '.' ) . take ( 2 ) . join ( '.' ) . to_f < 3.1
164+
165+ ractors = Array . new ( MAX_THREADS ) do |i |
166+ Ractor . new ( i ) do |i |
167+ c = ::RedisClient . cluster (
168+ nodes : TEST_NODE_URIS ,
169+ fixed_hostname : TEST_FIXED_HOSTNAME ,
170+ **TEST_GENERIC_OPTIONS
171+ ) . new_client
172+ c . pipelined do |pi |
173+ pi . call ( 'get' , "key#{ i } " )
174+ pi . call ( 'echo' , 'hi' )
175+ end
176+ rescue StandardError => e
177+ e
178+ ensure
179+ c &.close
180+ end
181+ end
182+
183+ ractors . each { |r | assert_equal ( [ WANT , 'hi' ] , r . take ) }
184+ end
185+
186+ def test_ractor_with_transaction
187+ skip ( 'Ractor is not available' ) unless Object . const_defined? ( :Ractor , false )
188+ skip ( "#{ RedisClient . default_driver } is not safe for Ractor" ) if RedisClient . default_driver != RedisClient ::RubyConnection
189+ skip ( 'OpenSSL gem has non-shareable objects' ) if TEST_REDIS_SSL
190+ skip ( 'test case may get stuck' ) if RUBY_ENGINE == 'ruby' && RUBY_ENGINE_VERSION . split ( '.' ) . take ( 2 ) . join ( '.' ) . to_f < 3.1
191+
192+ ractors = Array . new ( MAX_THREADS ) do |i |
193+ Ractor . new ( i ) do |i |
194+ c = ::RedisClient . cluster (
195+ nodes : TEST_NODE_URIS ,
196+ fixed_hostname : TEST_FIXED_HOSTNAME ,
197+ **TEST_GENERIC_OPTIONS
198+ ) . new_client
199+ c . multi ( watch : [ "key#{ i } " ] ) do |tx |
200+ tx . call ( 'incr' , "key#{ i } " )
201+ tx . call ( 'incr' , "key#{ i } " )
202+ end
203+ rescue StandardError => e
204+ e
205+ ensure
206+ c &.close
207+ end
208+ end
209+
210+ ractors . each { |r | assert_equal ( [ 2 , 3 ] , r . take ) }
211+ end
212+
135213 private
136214
137215 def new_test_client
0 commit comments