ruby-changes:63313
From: Benoit <ko1@a...>
Date: Sat, 10 Oct 2020 19:48:38 +0900 (JST)
Subject: [ruby-changes:63313] bfc1c7205d (master): Add Ractor#receive and Ractor.receive and use it in all places
https://git.ruby-lang.org/ruby.git/commit/?id=bfc1c7205d From bfc1c7205d9592b5b5be3b351fbf7b9ca8c537b6 Mon Sep 17 00:00:00 2001 From: Benoit Daloze <eregontp@g...> Date: Sat, 3 Oct 2020 14:05:15 +0200 Subject: Add Ractor#receive and Ractor.receive and use it in all places * Keep Ractor#recv/Ractor.recv as an alias for now. diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index f55b142..9e90d95 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -90,10 +90,10 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L90 } # Ractor#send passes an object with copy to a Ractor -# and Ractor.recv in the Ractor block can receive the passed value. +# and Ractor.receive in the Ractor block can receive the passed value. assert_equal 'ok', %q{ r = Ractor.new do - msg = Ractor.recv + msg = Ractor.receive end r.send 'ok' r.take @@ -196,7 +196,7 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L196 # Raise Ractor::ClosedError when try to send into a closed actor assert_equal 'ok', %q{ - r = Ractor.new { Ractor.recv } + r = Ractor.new { Ractor.receive } r.close begin @@ -212,7 +212,7 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L212 assert_equal 'ok', %q{ r = Ractor.new do Ractor.yield 1 - Ractor.recv + Ractor.receive end r.close @@ -228,14 +228,14 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L228 # Ractor.yield raises Ractor::ClosedError when outgoing port is closed. assert_equal 'ok', %q{ r = Ractor.new Ractor.current do |main| - Ractor.recv + Ractor.receive main << true Ractor.yield 1 end r.close_outgoing r << true - Ractor.recv + Ractor.receive begin r.take @@ -248,7 +248,7 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L248 # Raise Ractor::ClosedError when try to send into a ractor with closed incoming port assert_equal 'ok', %q{ - r = Ractor.new { Ractor.recv } + r = Ractor.new { Ractor.receive } r.close_incoming begin @@ -275,7 +275,7 @@ assert_equal '[1, 2]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L275 assert_equal 'ok', %q{ r = Ractor.new do Ractor.yield 1 - Ractor.recv + Ractor.receive end sleep 0.01 # wait for Ractor.yield in r @@ -292,7 +292,7 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L292 # A ractor with closed outgoing port still can receive messages from incoming port assert_equal 'ok', %q{ r = Ractor.new do - Ractor.recv + Ractor.receive end r.close_outgoing @@ -305,11 +305,11 @@ assert_equal 'ok', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L305 end } -# multiple Ractors can recv (wait) from one Ractor +# multiple Ractors can receive (wait) from one Ractor assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -330,7 +330,7 @@ assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L330 }.sort } -# Ractor.select also support multiple take, recv and yiled +# Ractor.select also support multiple take, receive and yield assert_equal '[true, true, true]', %q{ RN = 10 CR = Ractor.current @@ -341,29 +341,29 @@ assert_equal '[true, true, true]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L341 'take' end } - recv = [] + received = [] take = [] - yiel = [] + yielded = [] until rs.empty? r, v = Ractor.select(CR, *rs, yield_value: 'yield') case r - when :recv - recv << v + when :receive + received << v when :yield - yiel << v + yielded << v else take << v rs.delete r end end - [recv.all?('sendyield'), yiel.all?(nil), take.all?('take')] + [received.all?('sendyield'), yielded.all?(nil), take.all?('take')] } # multiple Ractors can send to one Ractor assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ pipe = Ractor.new do loop do - Ractor.yield Ractor.recv + Ractor.yield Ractor.receive end end @@ -378,7 +378,7 @@ assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L378 }.sort } -# an exception in a Ractor will be re-raised at Ractor#recv +# an exception in a Ractor will be re-raised at Ractor#receive assert_equal '[RuntimeError, "ok", true]', %q{ r = Ractor.new do raise 'ok' # exception will be transferred receiver @@ -420,7 +420,7 @@ assert_equal 'no _dump_data is defined for class Thread', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L420 assert_equal "ok", %q{ echo_ractor = Ractor.new do loop do - v = Ractor.recv + v = Ractor.receive Ractor.yield v end end @@ -518,7 +518,7 @@ assert_equal [false, true, false].inspect, %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L518 assert_equal 'hello world', %q{ # move r = Ractor.new do - obj = Ractor.recv + obj = Ractor.receive obj << ' world' end @@ -538,7 +538,7 @@ assert_equal 'hello world', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L538 # move example2: Array assert_equal '[0, 1]', %q{ r = Ractor.new do - ary = Ractor.recv + ary = Ractor.receive ary << 1 end @@ -746,7 +746,7 @@ assert_equal '[1000, 3]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L746 assert_equal '[1, 4, 3, 2, 1]', %q{ counts = [] counts << Ractor.count - ractors = (1..3).map { Ractor.new { Ractor.recv } } + ractors = (1..3).map { Ractor.new { Ractor.receive } } counts << Ractor.count ractors[0].send('End 0').take diff --git a/doc/ractor.md b/doc/ractor.md index b0a8fc1..7867ca3 100644 --- a/doc/ractor.md +++ b/doc/ractor.md @@ -68,7 +68,7 @@ Ractor helps to write a thread-safe program, but we can make thread-unsafe progr https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L68 * Some kind of shareable objects can introduce transactions (STM, for example). However, misusing transactions will generate inconsistent state. Without Ractor, we need to trace all of state-mutations to debug thread-safety issues. -With Ractor, you can concentrate to suspicious +With Ractor, you can concentrate to suspicious ## Creation and termination @@ -96,7 +96,7 @@ The Ractor execute given `expr` in a given block. https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L96 Given block will be isolated from outer scope by `Proc#isolate`. ```ruby -# To prevent sharing unshareable objects between ractors, +# To prevent sharing unshareable objects between ractors, # block outer-variables, `self` and other information are isolated. # Given block will be isolated by `Proc#isolate` method. # `Proc#isolate` is called at Ractor creation timing (`Ractor.new` is called) @@ -133,7 +133,7 @@ r.take #=> 'ok' https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L133 ```ruby # almost similar to the last example r = Ractor.new do - msg = Ractor.recv + msg = Ractor.receive msg end r.send 'ok' @@ -180,22 +180,22 @@ end https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L180 Communication between Ractors is achieved by sending and receiving messages. * (1) Message sending/receiving - * (1-1) push type send/recv (sender knows receiver). similar to the Actor model. + * (1-1) push type send/receive (sender knows receiver). similar to the Actor model. * (1-2) pull type yield/take (receiver knows sender). * (2) Using shareable container objects (not implemented yet) Users can control blocking on (1), but should not control on (2) (only manage as critical section). -* (1-1) send/recv (push type) +* (1-1) send/receive (push type) * `Ractor#send(obj)` (`Ractor#<<(obj)` is an aliases) send a message to the Ractor's incoming port. Incoming port is connected to the infinite size incoming queue so `Ractor#send` will never block. - * `Ractor.recv` dequeue a message from its own incoming queue. If the incoming queue is empty, `Ractor.recv` calling will block. + * `Ractor.receive` dequeue a message from its own incoming queue. If the incoming queue is empty, `Ractor.receive` calling will block. * (1-2) yield/take (pull type) * `Ractor.yield(obj)` send an message to a Ractor which are calling `Ractor#take` via outgoing port . If no Ractors are waiting for it, the `Ractor.yield(obj)` will block. If multiple Ractors are waiting for `Ractor.yield(obj)`, only one Ractor can receive the message. * `Ractor#take` receives a message which is waiting by `Ractor.yield(obj)` method from the specified Ractor. If the Ractor does not call `Ractor.yield` yet, the `Ractor#take` call will block. -* `Ractor.select()` can wait for the success of `take`, `yield` and `recv`. +* `Ractor.select()` can wait for the success of `take`, `yield` and `receive`. * You can close the incoming port or outgoing port. * You can close then with `Ractor#close_incoming` and `Ractor#close_outgoing`. - * If the incoming port is closed for a Ractor, you can't `send` to the Ractor. If `Ractor.recv` is blocked for the closed incoming port, then it will raise an exception. + * If the incoming port is closed for a Ractor, you can't `send` to the Ractor. If `Ractor.receive` is blocked for the closed incoming port, then it will raise an exception. * If the outgoing port is closed for a Ractor, you can't call `Ractor#take` and `Ractor.yield` on the Ractor. If `Ractor#take` is blocked for the Ractor, then it will raise an exception. * When a Ractor is terminated, the Ractor's ports are closed. * Ther (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/