socketry / async

An awesome asynchronous event-driven reactor for Ruby.
MIT License
2.15k stars 89 forks source link

Better handling of bare `Async` and `Sync` blocks when a scheduler is defined. #340

Closed ioquatix closed 3 months ago

ioquatix commented 3 months ago

Nested fibers can cause issues with Async, when spawning child tasks within them. I was affected by this issue when trying to create a streaming response from a Rails controller, using the proc do |stream| ... Async{....} end style response body. However, protocol-rack uses a normal fiber to wrap streaming responses and the child Async task has no parent, causing it to try and create a new event loop... meltdown ensues.

Ideally, Async and Sync helpers should work when any Fiber.scheduler is defined. Right now, it's unrealistic to expect Async::Task to work in any scheduler, but at the very least, the following should work:

reactor = Async::Reactor.new # internally calls Fiber.set_scheduler

# This should run in the above reactor:
Async do
  puts "Hello World"
end

In order to do this, bare Async and Sync blocks should use Fiber.scheduler as a parent if possible.

Types of Changes

Contribution