diff --git a/readme.md b/readme.md index b9926150..b99dbc11 100644 --- a/readme.md +++ b/readme.md @@ -35,6 +35,10 @@ Please see the [project documentation](https://socketry.github.io/async/) for mo Please see the [project releases](https://socketry.github.io/async/releases/index) for all releases. +### Next + + - [Better Handling of Async and Sync in Nested Fibers](https://socketry.github.io/async/releases/index#better-handling-of-async-and-sync-in-nested-fibers) + ## See Also - [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client/server. diff --git a/releases.md b/releases.md index e69de29b..3bc26f9a 100644 --- a/releases.md +++ b/releases.md @@ -0,0 +1,24 @@ +# Changes + +## Next + +### Better Handling of Async and Sync in Nested Fibers + +Interleaving bare fibers within `Async` and `Sync` blocks should not cause problems, but it presents a number of issues in the current implementation. Tracking the parent-child relationship between tasks, when they are interleaved with bare fibers, is difficult. The current implementation assumes that if there is no parent task, then it should create a new reactor. This is not always the case, as the parent task might not be visible due to nested Fibers. As a result, `Async` will create a new reactor, trying to stop the existing one, causing major internal consistency issues. + +I encountered this issue when trying to use `Async` within a streaming response in Rails. The `protocol-rack` [uses a normal fiber to wrap streaming responses](https://github.com/socketry/protocol-rack/blob/cb1ca44e9deadb9369bdb2ea03416556aa927c5c/lib/protocol/rack/body/streaming.rb#L24-L28), and if you try to use `Async` within it, it will create a new reactor, causing the server to lock up. + +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: + +```ruby +reactor = Async::Reactor.new # internally calls Fiber.set_scheduler + +# This should run in the above reactor, rather than creating a new one. +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. + +See for more details.