Project

General

Profile

Actions

Bug #22211

open

Fiber::Scheduler stalls on Ractor::Port.receive

Bug #22211: Fiber::Scheduler stalls on Ractor::Port.receive

Added by rkh (Konstantin Haase) 1 day ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 4.1.0dev (2026-07-24T12:18:38Z master 180b664bd9) +PRISM [arm64-darwin25]
[ruby-core:126158]

Description

Quickly upfront: This might be a duplicate of #20276, and let me know if the official solution is still to launch a thread for each port so it can block (or add some more complex thread orchestration).

Anyway, I think Ractor::Port#receive should call Fiber::Scheduler#block/Fiber::Scheduler#unblock if a scheduler is set (or some other hook), the way that Thread::Queue does. Instead, it completely blocks the scheduler.

Example to reproduce:

Warning[:experimental] = false

class Scheduler
  def initialize
    @fiber   = Fiber.current
    @blocked = Set.new
    @ready   = Queue.new
  end

  def scheduler_close
    @ready.pop.transfer while @blocked.any?
  end

  def block(blocker, timeout = nil)
    raise NotImplementedError, "block: timeout not supported" if timeout
    @blocked << Fiber.current
    @fiber.transfer
  ensure
    @blocked.delete(Fiber.current)
  end

  def unblock(blocker, fiber)              = @ready << fiber
  def io_write(io, buffer, offset, length) = Thread.new { buffer.write(io, offset, length) }.value
  def fiber(&)                             = Fiber.new(blocking: false, &).tap(&:transfer)
  def respond_to_missing?(...)             = true
  def method_missing(method, ...)          = raise NotImplementedError, "#{method}: not implemented"
end

Fiber.set_scheduler(Scheduler.new)

# This would work:
#
#   queue = Queue.new
#   Fiber.schedule { puts queue.pop }
#   queue.push "Hello from Queue!"

port = Ractor::Port.new
Fiber.schedule { puts port.receive }
port.send("Hello from Ractor::Port!") # never gets here

No data to display

Actions

Also available in: PDF Atom