Bug #20346
closedFiberScheduler.unblock not called by Thread#join when Thread body contains Ractor.take
Description
When using a Ractor.take inside a different thread, Thread#join on the thread running Ractor.take fails to call FiberScheduler.unblock. The below code can replicate this behavior
require "async"
class RactorWrapper
def initialize
@ractor = Ractor.new do
Ractor.recv # Ractor doesn't start until explicitly told to
# Do some calculations
fib = ->(x) { x < 2 ? 1 : fib.call(x - 1) + fib.call(x - 2) }
fib.call(20)
end
end
def take_async
@ractor.send(nil)
Thread.new { @ractor.take }.join.value
end
end
Async do |task|
10000.times do |i|
task.async do
RactorWrapper.new.take_async
puts i
end
end
end
The above code deadlocks, and when we leave a debugging print statement inside of Async's scheduler's block and unblock method, we can confirm that we only call Scheduler.block, and never Scheduler.unblock
Updated by jpcamara (JP Camara) over 1 year ago
Looks as though the fiber scheduler is not supported by Ractors right now, due to fixes that need to be implemented in the Ractor API. Not clear if it is expected to be fixed for 3.4 or not.

Updated by jhawthorn (John Hawthorn) 6 months ago
- Assignee set to ractor
Updated by hsbt (Hiroshi SHIBATA) 5 months ago
- Status changed from Open to Assigned
Updated by luke-gru (Luke Gruber) 5 months ago
I created a PR for this: https://github.com/ruby/ruby/pull/13517
Updated by jhawthorn (John Hawthorn) 2 months ago
- Status changed from Assigned to Closed
This no longer deadlocks. Under the new Ractor API the take should be replaced with value.
require "async"
class RactorWrapper
def initialize
@ractor = Ractor.new do
Ractor.recv # Ractor doesn't start until explicitly told to
# Do some calculations
fib = ->(x) { x < 2 ? 1 : fib.call(x - 1) + fib.call(x - 2) }
fib.call(20)
end
end
def take_async
@ractor.send(nil)
Thread.new { @ractor.value }.value
end
end
Async do |task|
10000.times do |i|
task.async do
RactorWrapper.new.take_async
puts i
end
end
end
I recorded a profile showing that the concurrency is happening properly (warning: this has 10k threads of data) https://share.firefox.dev/4lCxnFK