core/ractor.rbs in rbs-2.0.0 vs core/ractor.rbs in rbs-2.1.0
- old
+ new
@@ -1,17 +1,18 @@
+# <!-- rdoc-file=ractor.rb -->
# Ractor is a Actor-model abstraction for Ruby that provides thread-safe
# parallel execution.
#
-# Ractor.new can make new Ractor and it will run in parallel.
+# Ractor.new can make a new Ractor, and it will run in parallel.
#
# # The simplest ractor
# r = Ractor.new {puts "I am in Ractor!"}
-# r.take # wait it to finish
+# r.take # wait for it to finish
# # here "I am in Ractor!" would be printed
#
-# Ractors do not share usual objects, so the some kind of thread-safety concerns
-# such as data-race, race-conditions are not available on multi-ractor
+# Ractors do not share usual objects, so the same kinds of thread-safety
+# concerns such as data-race, race-conditions are not available on multi-ractor
# programming.
#
# To achieve this, ractors severely limit object sharing between different
# ractors. For example, unlike threads, ractors can't access each other's
# objects, nor any objects through variables of the outer scope.
@@ -154,11 +155,11 @@
#
# Notice that even `inspect` (and more basic methods like `__id__`) is
# inaccessible on a moved object.
#
# Besides frozen objects, there are shareable objects. Class and Module objects
-# are shareable so the Class/Module definitons are shared between ractors.
+# are shareable so the Class/Module definitions are shared between ractors.
# Ractor objects are also shareable objects. All operations for the shareable
# mutable objects are thread-safe, so the thread-safety property will be kept.
# We can not define mutable shareable objects in Ruby, but C extensions can
# introduce them.
#
@@ -204,11 +205,11 @@
# r.take
# # I see C
# # can not access instance variables of classes/modules from non-main Ractors (RuntimeError)
#
# See also the description of `# shareable_constant_value` pragma in [Comments
-# syntax](rdoc-ref:doc/syntax/comments.rdoc) explanation.
+# syntax](rdoc-ref:syntax/comments.rdoc) explanation.
#
# ## Ractors vs threads
#
# Each ractor creates its own thread. New threads can be created from inside
# ractor (and, on CRuby, sharing GVL with other threads of this ractor).
@@ -233,12 +234,17 @@
# It is **only for demonstration purposes** and shouldn't be used in a real
# code. Most of the times, just #take is used to wait till ractor will finish.
#
# ## Reference
#
-# See [Ractor desgin doc](rdoc-ref:doc/ractor.md) for more details.
+# See [Ractor design doc](rdoc-ref:ractor.md) for more details.
+#
class Ractor
+ # <!--
+ # rdoc-file=ractor.rb
+ # - count()
+ # -->
# Returns total count of Ractors currently running.
#
# Ractor.count #=> 1
# r = Ractor.new(name: 'example') { Ractor.yield(1) }
# Ractor.count #=> 2 (main + example ractor)
@@ -246,20 +252,32 @@
# r.take # wait till r will finish
# Ractor.count #=> 1
#
def self.count: () -> Integer
+ # <!--
+ # rdoc-file=ractor.rb
+ # - current()
+ # -->
# Returns the currently executing Ractor.
#
# Ractor.current #=> #<Ractor:#1 running>
#
def self.current: () -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - main()
+ # -->
# returns main ractor
#
def self.main: () -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.make_shareable(obj, copy: false) -> shareable_obj
+ # -->
# Make `obj` shareable between ractors.
#
# `obj` and all the objects it refers to will be frozen, unless they are already
# shareable.
#
@@ -291,10 +309,14 @@
# See also the "Shareable and unshareable objects" section in the Ractor class
# docs.
#
def self.make_shareable: [T] (T obj, ?copy: boolish) -> T
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.new(*args, name: nil) {|*args| block } -> ractor
+ # -->
# Create a new Ractor with args and a block.
#
# A block (Proc) will be isolated (can't access to outer variables). `self`
# inside the block will refer to the current Ractor.
#
@@ -322,10 +344,14 @@
# p r
# #=> #<Ractor:#3 my ractor test.rb:1 terminated>
#
def self.new: (*untyped args, ?name: string) { (*untyped) -> untyped } -> Ractor
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.receive -> msg
+ # -->
# Receive an incoming message from the current Ractor's incoming port's queue,
# which was sent there by #send.
#
# r = Ractor.new do
# v1 = Ractor.receive
@@ -380,10 +406,14 @@
# wait
# # in `receive': The incoming port is already closed => #<Ractor:#2 test.rb:1 running> (Ractor::ClosedError)
#
def self.receive: () -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.receive_if {|msg| block } -> msg
+ # -->
# Receive only a specific message.
#
# Instead of Ractor.receive, Ractor.receive_if can provide a pattern by a block
# and you can choose the receiving message.
#
@@ -402,11 +432,11 @@
# foo3
# bar1
# baz2
#
# If the block returns a truthy value, the message will be removed from the
- # incoming queue and returned. Otherwise, the messsage remains in the incoming
+ # incoming queue and returned. Otherwise, the message remains in the incoming
# queue and the following received messages are checked by the given block.
#
# If there are no messages left in the incoming queue, the method will block
# until new messages arrive.
#
@@ -437,12 +467,21 @@
# Ractor.receive_if{|msg| Ractor.receive}
# #=> `receive': can not call receive/receive_if recursively (Ractor::Error)
#
def self.receive_if: () { (untyped) -> boolish } -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - recv()
+ # -->
+ #
alias self.recv self.receive
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.select(*ractors, [yield_value:, move: false]) -> [ractor or symbol, obj]
+ # -->
# Waits for the first ractor to have something in its outgoing port, reads from
# this ractor, and returns that ractor and the object received.
#
# r1 = Ractor.new {Ractor.yield 'from 1'}
# r2 = Ractor.new {Ractor.yield 'from 2'}
@@ -486,12 +525,16 @@
# Received nil from :yield
#
# `move` boolean flag defines whether yielded value should be copied (default)
# or moved.
#
- def self.select: (*Ractor ractors, ?move: boolish, ?yield_value: untyped) -> [Ractor | Symbol, untyped]
+ def self.select: (*Ractor ractors, ?move: boolish, ?yield_value: untyped) -> [ Ractor | Symbol, untyped ]
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.shareable?(obj) -> true | false
+ # -->
# Checks if the object is shareable by ractors.
#
# Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are frozen
# Ractor.shareable?('foo') #=> false, unless the string is frozen due to # freeze_string_literals: true
# Ractor.shareable?('foo'.freeze) #=> true
@@ -499,10 +542,14 @@
# See also the "Shareable and unshareable objects" section in the Ractor class
# docs.
#
def self.shareable?: (untyped obj) -> bool
+ # <!--
+ # rdoc-file=ractor.rb
+ # - Ractor.yield(msg, move: false) -> nil
+ # -->
# Send a message to the current ractor's outgoing port to be consumed by #take.
#
# r = Ractor.new {Ractor.yield 'Hello from ractor'}
# puts r.take
# # Prints: "Hello from ractor"
@@ -537,20 +584,37 @@
#
def self.yield: (untyped obj, ?move: boolish) -> untyped
public
+ # <!--
+ # rdoc-file=ractor.rb
+ # - <<(obj, move: false)
+ # -->
+ #
alias << send
+ # <!--
+ # rdoc-file=ractor.rb
+ # - [](sym)
+ # -->
# get a value from ractor-local storage
#
def []: (Symbol | String sym) -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - []=(sym, val)
+ # -->
# set a value in ractor-local storage
#
def []=: [T] (Symbol | String sym, T val) -> T
+ # <!--
+ # rdoc-file=ractor.rb
+ # - ractor.close_incoming -> true | false
+ # -->
# Closes the incoming port and returns its previous state. All further attempts
# to Ractor.receive in the ractor, and #send to the ractor will fail with
# Ractor::ClosedError.
#
# r = Ractor.new {sleep(500)}
@@ -559,10 +623,14 @@
# r.send('test')
# # Ractor::ClosedError (The incoming-port is already closed)
#
def close_incoming: () -> bool
+ # <!--
+ # rdoc-file=ractor.rb
+ # - ractor.close_outgoing -> true | false
+ # -->
# Closes the outgoing port and returns its previous state. All further attempts
# to Ractor.yield in the ractor, and #take from the ractor will fail with
# Ractor::ClosedError.
#
# r = Ractor.new {sleep(500)}
@@ -571,16 +639,29 @@
# r.take
# # Ractor::ClosedError (The outgoing-port is already closed)
#
def close_outgoing: () -> bool
+ # <!--
+ # rdoc-file=ractor.rb
+ # - inspect()
+ # -->
+ #
def inspect: () -> String
+ # <!--
+ # rdoc-file=ractor.rb
+ # - name()
+ # -->
# The name set in Ractor.new, or `nil`.
#
def name: () -> String?
+ # <!--
+ # rdoc-file=ractor.rb
+ # - ractor.send(msg, move: false) -> self
+ # -->
# Send a message to a Ractor's incoming queue to be consumed by Ractor.receive.
#
# r = Ractor.new do
# value = Ractor.receive
# puts "Received #{value}"
@@ -658,10 +739,14 @@
# r.send(s, move: true)
# s.inspect #=> "message", still available
#
def send: (untyped obj, ?move: boolish) -> Ractor
+ # <!--
+ # rdoc-file=ractor.rb
+ # - ractor.take -> msg
+ # -->
# Take a message from ractor's outgoing port, which was put there by
# Ractor.yield or at ractor's finalization.
#
# r = Ractor.new do
# Ractor.yield 'explicit yield'
@@ -720,55 +805,193 @@
# Received: finishing
# Continue successfully
#
def take: () -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - to_s()
+ # -->
+ #
alias to_s inspect
private
+ # <!--
+ # rdoc-file=ractor.rb
+ # - receive()
+ # -->
# same as Ractor.receive
#
def receive: () -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - receive_if(&b)
+ # -->
+ #
def receive_if: () { (untyped) -> boolish } -> untyped
+ # <!--
+ # rdoc-file=ractor.rb
+ # - recv()
+ # -->
+ #
alias recv receive
+ # <!-- rdoc-file=ractor.c -->
+ # Raised when an attempt is made to send a message to a closed port, or to
+ # retrieve a message from a closed and empty port. Ports may be closed
+ # explicitly with Ractor#close_outgoing/close_incoming and are closed implicitly
+ # when a Ractor terminates.
+ #
+ # r = Ractor.new { sleep(500) }
+ # r.close_outgoing
+ # r.take # Ractor::ClosedError
+ #
+ # ClosedError is a descendant of StopIteration, so the closing of the ractor
+ # will break the loops without propagating the error:
+ #
+ # r = Ractor.new do
+ # loop do
+ # msg = receive # raises ClosedError and loop traps it
+ # puts "Received: #{msg}"
+ # end
+ # puts "loop exited"
+ # end
+ #
+ # 3.times{|i| r << i}
+ # r.close_incoming
+ # r.take
+ # puts "Continue successfully"
+ #
+ # This will print:
+ #
+ # Received: 0
+ # Received: 1
+ # Received: 2
+ # loop exited
+ # Continue successfully
+ #
class ClosedError < StopIteration
end
class Error < RuntimeError
end
class IsolationError < Ractor::Error
end
+ # <!-- rdoc-file=ractor.c -->
+ # Raised on an attempt to access an object which was moved in Ractor#send or
+ # Ractor.yield.
+ #
+ # r = Ractor.new { sleep }
+ #
+ # ary = [1, 2, 3]
+ # r.send(ary, move: true)
+ # ary.inspect
+ # # Ractor::MovedError (can not send any methods to a moved object)
+ #
class MovedError < Ractor::Error
end
+ # <!-- rdoc-file=ractor.c -->
+ # A special object which replaces any value that was moved to another ractor in
+ # Ractor#send or Ractor.yield. Any attempt to access the object results in
+ # Ractor::MovedError.
+ #
+ # r = Ractor.new { receive }
+ #
+ # ary = [1, 2, 3]
+ # r.send(ary, move: true)
+ # p Ractor::MovedObject === ary
+ # # => true
+ # ary.inspect
+ # # Ractor::MovedError (can not send any methods to a moved object)
+ #
class MovedObject < BasicObject
public
+ # <!--
+ # rdoc-file=ractor.c
+ # - !(*args)
+ # -->
+ #
def !: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - !=(*args)
+ # -->
+ #
def !=: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - ==(*args)
+ # -->
+ #
def ==: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - __id__(*args)
+ # -->
+ #
def __id__: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - __send__(*args)
+ # -->
+ #
def __send__: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - equal?(*args)
+ # -->
+ #
def equal?: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - instance_eval(*args)
+ # -->
+ #
def instance_eval: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - instance_exec(*args)
+ # -->
+ #
def instance_exec: (*untyped) -> untyped
+ # <!--
+ # rdoc-file=ractor.c
+ # - method_missing(*args)
+ # -->
+ #
def method_missing: (*untyped) -> untyped
end
+ # <!-- rdoc-file=ractor.c -->
+ # Raised on attempt to Ractor#take if there was an uncaught exception in the
+ # Ractor. Its `cause` will contain the original exception, and `ractor` is the
+ # original ractor it was raised in.
+ #
+ # r = Ractor.new { raise "Something weird happened" }
+ #
+ # begin
+ # r.take
+ # rescue => e
+ # p e # => #<Ractor::RemoteError: thrown by remote Ractor.>
+ # p e.ractor == r # => true
+ # p e.cause # => #<RuntimeError: Something weird happened>
+ # end
+ #
class RemoteError < Ractor::Error
public
def ractor: () -> Ractor
end