Hi Edmond, > On Oct 22, 2025, at 15:43, Edmond Dantes <[email protected]> wrote: > > Hi > >> * Is TrueAsync intended strictly to enable concurrency without parallelism >> (e.g. single-threaded cooperative multitasking)? >> Is there a future path in mind for parallelism (actual simultaneous >> execution)? > > In short, it mostly depends on the PHP core. TrueAsync itself could > support multithreading. > At the moment, achieving a fully multithreaded PHP seems extremely > complex and offers very little benefit. > In other words, the cost-to-benefit ratio is close to “irrational.” > > If you’d like, I can elaborate on this idea, though probably not in this > thread.
To be clear, since I didn't explicitly state this, my point is that I would like to see whatever gets introduced by any RFC (as this one is) that is likely to be used as a stepping stone to full multithreaded async PHP (whether or not we think that such a destination is likely on any practical timescale) _NOT_ get in the way of that destination. That is, I don't want us to go partway down a path, only to find later that we can't make it to the destination because of a bad or incomplete decision early on. Which is why I'm asking about stuff that might not be in scope for this RFC, because it _will_ be in-scope for some future RFC, and if we wind up with a bad interface now, it makes that future RFC's job unnecessary harder. And since this isn't going to be shipping to any end-user for at least another year, we have _plenty_ of time to make sure we get the interface right. >> * Rob Landers brought up the question about multiple-value Awaitables. >> I agree with him that it is a potential footgun. If an Awaitable is going to >> return multiple values, then it should implement have a different interface >> to indicate that contract. > > It seems to me that this discussion has gotten a bit tangled: > > 1. Functions like awaitXX are not part of this RFC, yet we’re > discussing them. Is that really necessary? I can't find where this `awaitXX` function is defined, so I can't comment on that. But I didn't bring it up, so I'm unclear why you are. > 2. Awaitable objects do not return multiple values. So you say "Awaitable objects do not return multiple values." but the description of the Awaitable interface says it allows for that. Unless I'm misunderstanding something, I don't think that makes any sense. And also you seem to be saying that some objects are Awaitable, and also there's an Awaitable interface that means something different, which is definitely going to cause confusion. > 3. The Awaitable interface is basic for others, just like in many > other programming languages. And for some reason, it’s not considered > a problem there. > So far, no real example has been found where this would actually be a problem. This may not be your intention, but to me it feels like you're just dismissing Rob and my concern, which is that single-value and multiple-value are two completely different beasts and PHP shouldn't allow you to just casually mix them without throwing a compile-time error. Rob has provided an example where this _is_ a problem. And Swift does recognize this as a problem, that's why if you want to iterate on the result of an asynchronous stream of values, you use an AsyncStream, and not a Task/Coroutine. (Granted: the stream's values might be sourced from within a Task, but that's an implementation detail. And why there's also a TaskGroup if what you want is to spawn a one async task per item in an iterable and iterate over the results as they complete.) (btw, if you haven't read through the Swift Evolution proposals for structured concurrency, I highly recommend you do, if only to see what/how Swift has chosen to do. And then what they got wrong and the hoops they jumped through to try and remedy it afterwards, some of which many people here would find quite distasteful.) >> For cancellation, I'm confused on the resulting value. > Thank you, that’s a great catch!!! > I need to check this case. > >> For clarity, the case when exit/die is called outside of async code > In TrueAsync, there is no longer any non-asynchronous code. Everything > is a coroutine. > Actually, that’s not entirely accurate, but it’s fine to think of it that way. Then, just saying, this is a place where people are going to be confused, and it needs to be stated clearly. The description in "exit and die keywords" section shouldn't be under cancellation policy, and shouldn't special-case being called within a coroutine. If exit/die still immediately terminate execution, then there should be no confusion about that. >> I think Async\protect() and forcibly cancelling coroutines beyond calling >> $coroutine->cancel() should be removed. > > If PHP were a language for spacecraft or airplanes, where extremely > high reliability is required, this might make sense. > However, the current model allows for more concise code and has > already proven itself well in other languages. There may be a misunderstanding here. I'm not saying you should remove cooperative cancelation. That's perfectly fine and should stay. With cooperative cancellation, it's not necessary to assert you're in a critical section, you just ignore the cancellation signal and keep on processing. What I'm proposing that specifically Async\protect() and *forcibly* cancelling coroutines should be removed. (You'll note that in some multithreading APIs, forcibly terminating threads, while allowed, is very much discouraged because that can leave things in inconsistent states that causes future crashes or unpredictable behavior.) > I actually have a stricter explanation for why the cancellable model > is more advantageous than any other. > This particular model fits well for read operations, which are usually > as frequent as, or even more frequent than, write operations. > Therefore, this approach simplifies asynchronous code while keeping > the overall risk low. The RFC should include a description of _why_ cooperative cancellation has been chosen. > Thanks, Ed -John
