Hi

> One minor question: is this section 
> https://wiki.php.net/rfc/true_async#awaiting_a_result_with_cancellation named 
> wrongly? I'm not sure how this snippet of code relates to cancellation.
Yes, second parameter is a CancellationToken. (spawn('sleep', 2)).

> What's the difference between Multishot Awaitables and Generators?
There’s nothing in common between them.
It’s better to think of asynchronous objects as components of an
EventDriven pattern.

> doesn't this mean that multishot awaitables are not really capable of being 
> awaited anymore?
Exactly. It’s not needed for now.

> Shouldn't FutureLike be Awaitable and what has been described as Multishot 
> awaitables should actually be generators / array of / list of Awaitables?
FutureLike is a child interface of Awaitables.

> we can assume that if a function used to throw an Exception and a future 
> version stops throwing said exception it is not considered a BC Break.
This RFC does not change the behavior of existing functions. For
example, sleep works the same as before.
PHP functions that previously did not throw a CancellationError do not
throw it in this RFC either.
However, when you use functions (await example) that do throw these
exceptions, you handle them the same way as always. In that sense,
there’s no new paradigm.

> What if the first version of Async PHP provides userland with the ability to 
> trigger coroutines for reading purposes only?

Sorry, but I couldn’t understand why this needs to be done.
There’s nothing terrible about canceling write operations — no
“shooting yourself in the foot” either. A program can terminate at any
moment; that’s perfectly normal.

The concept of Cancellation by Design isn’t about guns — it’s about
reducing code. That’s all.
In the Swift language, for example, a different concept is used:
cancellation is always written explicitly in the code, like this:

```swift
func fetchData() async throws -> String {
    for i in 1...5 {
        try Task.checkCancellation()
        print("Fetching chunk \(i)...")
        try await Task.sleep(nanoseconds: 500_000_000)
    }
    return "Data loaded"
}
```

The only question is about how much code you write and the likelihood
of errors. The more code you write, the higher the chance of making
one.

Write safety is a different topic; it concerns how code is implemented
at the lowest level, meaning the code that calls OS functions.
Cancelling a coroutine cannot interrupt a kernel-level write operation
— it can only interrupt waiting for the write, and what to do next is
decided by the user-level code.

The cancellation design was implemented as early as 2015 in Python
(and in other languages as well) and has worked perfectly since then.
For languages like PHP, it’s a convenient and, most importantly,
familiar mechanism. The real problem is that an exception can
accidentally be caught without exiting the coroutine. For example:
```php
catch (\Throwable $e) {
    Logger::log();
}
continue;
```

Reply via email to