Re: PHP True Async RFC Stage 4

From: Date: Thu, 16 Oct 2025 11:31:21 +0000
Subject: Re: PHP True Async RFC Stage 4
References: 1 2 3 4 5 6 7  Groups: php.internals 
Request: Send a blank email to internals+get-128853@lists.php.net to get a copy of this message

On Thu, Oct 16, 2025, at 09:38, Daniil Gentili wrote:
> 
> > You've provided examples and said that it violates design and fundamental elements,
> > but not which design and fundamentals, ie, the evidence for the decision. I would expect more than
> > "because I said so" for such a huge language feature, but rather arguments grounded in
> > computer science. 
> 
> 
> He very explicitly described the issue, in objective terms: a breach of agreement in the
> context of the invocation of a foreign interface.
> 
> In simpler terms, you can't and should not be able to mess with the internals of code you
> didn't write: this is similar to the principle of encapsulation in OOP, where you cannot modify
> private properties of an object.
> 
> 
> Cancellation should be part of the contract of an async function: it is safe, and most async
> languages already implement it explicitly by passing a context or a cancellation token, the current
> approach of the RFC does it implicitly, which is also fine.
> 
> Awaiting for the completion of spawned coroutines should *not* be part of the contract of an
> async function: it is an incredibly easy footgun, as it's incredibly easy to spawn a coroutine
> meant to i.e. run until the object is destroyed, and then encounter a deadlock when the linked scope
> is awaited for before the object is destroyed (even messier if cycles and thus the GC are involved).
> 
> Languages like Kotlin that do implement await on scopes have already realized that it is a
> mistake, as can be seen by the many warnings against using await on a scope, as I already linked in
> previous emails.
> 
> On the other hand, making the same mistake described above, by cancelling a scope, will produce
> a very easy to debug exception instead of a deadlock, easily fixable by (warning the author of the
> library class) to use a new scope to spawn coroutines within the object.
> 
> Awaiting a scope leads to deadlocks in case where a separate scope is needed but not used,
> cancelling them leads to a simple exception.
> Awaiting on multiple tasks can already be done, explicitly, with TaskGroup.
> 
> 
> Regards,
> Daniil Gentili.

Hey Daniil and Edmond,

I think I understand the intention. Would it be better to instead of having ->awaitCompletion
(which feels like an implicit implementation of Awaitable without an explicit implmentation -- which
is the part that was bothering me), maybe having something like ->joinAll() or
->joinOnCancellation()? That way someone like me won't come along and wrap them in an
Awaitable because it looks Awaitable.

It also might be a good idea to make specifying a timeout in ms mandatory, instead of a taking an
Awaitable/Cancellation. This would also prevent people from simply passing a "never
returning" Awaitable thinking they're being clever.

It also might be good to provide a realistic looking example showing a "bad case" of how
this is dangerous instead of simply saying that it is, showing how a scope is not a
'future', but a container, and preemptively mention TaskGroups, linking to the future
scope (which it should also probably be listed there as well).

— Rob


Thread (104 messages)

« previous php.internals (#128853) next »