Actions
Bug #22211
openFiber::Scheduler stalls on Ractor::Port.receive
Bug #22211:
Fiber::Scheduler stalls on Ractor::Port.receive
Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 4.1.0dev (2026-07-24T12:18:38Z master 180b664bd9) +PRISM [arm64-darwin25]
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