Re: Re: PHP True Async RFC Stage 5

From: Date: Fri, 07 Nov 2025 09:45:10 +0000
Subject: Re: Re: PHP True Async RFC Stage 5
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-129128@lists.php.net to get a copy of this message
Hello, Luís.

> Maybe keep the base Awaitable internal and expose two userland interfaces that match the two
> cases described in the RFC:

Yes, that option is possible, but I want to share my current line of thinking:
1. I’d really like to keep the name Future for the Future class,
which is planned for upcoming RFCs.
2. I have some doubts that the name Streamable precisely conveys the
intended meaning (example Signals). However, if our colleagues who are
native English speakers say it’s a good choice, I have no objections.

> Questions (self-cancellation) 1. What happens here?

Here’s what happens:
1. The coroutine continues running successfully until completion.
2. The code that calls await() receives a
CancellationError("Self-cancelled") exception.

Originally, the idea was to throw an exception directly from
cancel(), but that would require adding an extra try-catch block.
So I decided to keep it silent instead.

> Can a cancelled coroutine suspend?

Nothing will happen.
When cancel() is called, PHP detects that it’s the current coroutine
and only sets the exception as its result.
Later, when suspend() is invoked, it creates a new waker object that
has no exception, so after resuming, no exception occurs.

Do you think this case should be additionally described in the RFC?
So, that would give developers a better understanding.
Sometimes a coroutine doesn’t cancel itself but its own Scope,
and the developer should understand that if they cancel a Scope that
includes the current coroutine, they need to finish its work properly
from within.

> Which error does await() throw in this case — CancellationError or RuntimeException?

RuntimeException, because this exception will override the previous one.
There is more logic here than described in the RFC, because there is
an “override” rule.
Exceptions of the CancellationError class do not override each
other. The first cancellation reason is always visible.
However, if an unhandled exception of another class occurs, it will
replace the CancellationError.

In other words, the logic follows these rules:
1. The first cancellation reason takes precedence over subsequent ones.
2. Unexpected errors take precedence over CancellationError.

So, when a developer tries to cancel a coroutine more than once, it
has no effect.

> It’d be great to clarify that in the docs, since it affects where people put cleanup,
> logging, etc.

This case should be described in more detail in the RFC.
Thank you for noticing it!

> Again, thanks for the work, especially on such an important feature for PHP’s future.
Thank you for your excellent feedback, it’s very inspiring.

---
Best Regards, Ed


Thread (3 messages)

« previous php.internals (#129128) next »