Hello,

I have serious concerns about any approach that may cause the event loop to
block. The correct ways to handle this should not involve blocking the loop
— whether globally or in a scoped manner — while attempting to let
synchronous and asynchronous code coexist in the same environment. More
appropriate alternatives would be offloading execution to another thread
(which is far too complex for the current VM and ecosystem) or relying on
preemption (which is not feasible to implement here).

In addition, the cascading effects of such an approach are significant:
libraries would be forced to implement internal mechanisms just to deal
with unexpected loop stalls and similar issues.

It would be much healthier for new libraries to be designed specifically
for the asynchronous environment, in the same way Laravel created Octane to
run on top of Swoole.

Kind regards,
Luís Vinícius.

Rowan Tommins [IMSoP] <[email protected]> escreveu (domingo, 23/11/2025
à(s) 18:58):

> On 23/11/2025 19:09, Edmond Dantes wrote:
>
> @Ed Unless something calls `spawn` all I/O is going to be blocking &
> non-concurrent, correct?
>
> Yes.
> If no one calls spawn, this is equivalent to the code running inside a
> single coroutine.
>
> At the moment, TrueAsync has an internal flag that allows it to be
> enabled or disabled. If Async is disabled, an exception will be
> thrown.
>
>
> I think there's a lot of confusion in this thread because different people
> are talking about different scenarios. Perhaps it would be useful to
> introduce some User Stories...
>
>
> Async Alice is working on a brand new application written in PHP 9, and is
> designing it from the ground up to make use of async capabilities wherever
> possible. She wants third-party libraries to use async I/O so that she can
> use them in her design.
>
> Beginner Bob has a recently built application, and thinks there's an
> opportunity to improve it with async I/O, but doesn't know anything about
> it. He wants a simple-to-use API that lets him get the benefits, and clear
> instructions on what pitfalls to look out for.
>
> Legacy Les is maintaining a 20-year-old business back office system, which
> makes extensive use of global state and does not have good automated
> testing. He wants to run it under PHP 9, and to use up-to-date third-party
> libraries for new functionality, without an expensive and risky rewrite of
> existing code.
>
> Finally, SDK Susie is publishing the official PHP library for a popular
> cloud API. She wants to serve the best version she can for Alice, Bob, and
> Les, but doesn't want to maintain separate "sync" and "async" branches of
> the library or its methods.
>
> Feel free to create more personas if you want to talk about additional
> scenarios.
>
>
> The first thing I want to clarify is that SDK Susie doesn't necessarily
> need to change the public methods of her library; she can still use async
> I/O internally. For instance, if a method already returns an Iterator to
> silently fetch a page of results at a time, that can be changed to store
> Promises internally, and await them when the data is needed.
>
> However, she might want to mark it as a breaking change anyway, so
> that Async Alice and Beginner Bob know they are opting into it.
>
>
> Legacy Les won't get it until he opts in, but at some point he will need a
> new version of the library for other reasons (e.g. because the cloud API
> becomes incompatible with the old library version); so he still needs a way
> to run it safely.
>
> If he runs PHP in a mode where any attempt to use async I/O *throws an
> error*, he still can't use the new version of the library, so this doesn't
> help him.
>
>
> However, if Legacy Les can run PHP in a mode where any attempt to use
> async I/O is *automatically run synchronously*, then he will be happy: he
> can run his legacy application under PHP 9, and use the updated library,
> without worrying about async code.
>
> Beginner Bob doesn't want to run his whole application in "sync only"
> mode, but might want to switch *parts of it*, so that he doesn't have to
> think about them yet. So a scoped, rather than global, switch might be
> useful for him.
>
>
> This is how I picture that mode working: when SDK Susie's library code
> calls "spawn", a Coroutine is created as normal. However, when it suspends,
> the Scheduler immediately resumes it, rather than switching to a different
> Coroutine. The library code will see the Coroutine object it expects, but
> passing it to "await" will immediately produce its result.
>
> However, I might well be misunderstanding something, and this is either
> impossible or difficult to implement. If so, I think some other solution to
> Legacy Les's requirements is needed.
>
>
> I hope this description is useful.
>
>
> --
> Rowan Tommins
> [IMSoP]
>
>

Reply via email to