Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
Ractor::Port#receive
# File tmp/rubies/ruby-4.1.0-preview1/ractor.rb, line 793
def receive(timeout: nil)
__builtin_cexpr! %q{
ractor_port_receive(ec, self, timeout)
}
end
Receives a message from the port (which was sent there by Port#send). Only the ractor that created the port can receive messages this way.
port = Ractor::Port.new r = Ractor.new port do |port| port.send('message1') end v1 = port.receive puts "Received: #{v1}" r.join # This will print: "Received: message1"
The method blocks the current Thread if the message queue is empty.
port = Ractor::Port.new r = Ractor.new port do |port| wait puts "Still not received" port.send('message1') wait puts "Still received only one" port.send('message2') end puts "Before first receive" v1 = port.receive puts "Received: #{v1}" v2 = port.receive puts "Received: #{v2}" r.join
Output:
Before first receive Still not received Received: message1 Still received only one Received: message2
With timeout (in seconds) the method gives up waiting and returns nil once it passes. A message that arrives just as the timeout expires is still returned; the timeout bounds the wait, it does not cut delivery off.
port = Ractor::Port.new port.receive(timeout: 0.1) #=> nil port.receive(timeout: 0) #=> nil
A timeout of 0 never blocks and reads no clock: it takes a message if one is already there and returns nil otherwise.
If the port is closed and there are no more messages in the message queue, the method raises Ractor::ClosedError. Closing a port while this method waits on it ends the wait the same way; messages queued before the close are received first.
port = Ractor::Port.new port.close port.receive #=> raise Ractor::ClosedError port = Ractor::Port.new Thread.new { sleep 0.1; port.close } port.receive #=> raise Ractor::ClosedError, after 0.1 seconds