Skip to content

Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →

instance method

Ractor::Port#receive

() -> T
port.receive(timeout: nil) → msg or nil

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.

Example
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.

Example
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.

Example
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.

Example
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
See also #inspect #send #closed? also in 4.0