> On 3 Mar 2025, at 13:05, Edmond Dantes <edmond...@gmail.com> wrote: > >> As a heavy use of both amphp and go, cancellations (contexts in go) are >> absolutely needed, as a fiber may spawn further background fibers in order >> to execute some operation, just cancelling that specific fiber will not >> cancel the spawned fibers, unless a bunch of boilerplate try-catch blocks >> are added to propagate CancellationExceptions. > > I didn't mean that Cancellation isn't needed at all. I meant that canceling a > Fiber is sufficient in most scenarios and leads to clean, understandable code. > > Other languages have child coroutines (Swoole supports them too), but I'm not > sure if that's the right approach. > > I like context.WithCancel from Go, but it can essentially be implemented > directly in PHP land since all the necessary tools are available. >
Note, this is precisely the problem, implement cancellation propagation to child fibers in userland PHP requires writing a bunch of boilerplate try-catch blocks to propagate CancellationExceptions to child FutureHandle::cancel()s (spawning multiple fibers to execute subtasks concurrently during an async method call is pretty common, and the current implicit cancellation mode requires writing a bunch of try-catch blocks to propagate cancellation, instead of just passing a cancellation object, or a flag to inherit the cancellation of the current fiber when spawning a new one). >> A nicer API should use only explicit cancellation objects, as this pattern >> of preemptive implicit cancellations > > The exception mechanism is the standard way to alter the execution flow in > PHP. If a programmer writes code with lock and unlock outside of a > try-finally block but calls functions between these methods, they are > potentially creating a bad solution—at the very least because someone else > might later introduce an exception in one of those functions. This is a > classic case for languages with exceptions. > Note the explicit use case I listed is that of an unlock() in a finally block that *requires spawning a new fiber* in order to execute the actual unlock() RPC call: this is explicitly in contrast with the RFC, which specifies that >ATTENTION: A programmer must never attempt to create a new fiber while >handling a CancellationException, as this behavior may trigger an exception >during Graceful Shutdown mode. While this is *somewhat* understandable in the context of graceful shutdown, it still means that unlocking in a finally block (the only way of properly handling cancellations with the current model) isn’t always possible.. > So far, I haven't found a better way to ensure the logical consistency and > integrity of the execution flow. Maybe someone has a suggestion? > >> The main reason given in the RFC > > The main reason is that PHP has been around for many years and didn’t just > appear yesterday. > > If you have an idea on how to start the Scheduler implicitly, let's implement > it. So far, I have a few ideas: > > Using an option in php.ini (downside: if PHP is used for multiple projects). > Using a CLI option – so far, I like this the most. I would really prefer it to be always enabled, no fallback at all, because as I said, it will make absolutely no difference to legacy, non-async projects that do not use fibers, but it will avoid a split ecosystem scenario. >> A thing I would love to see, on the other hand, is for Context to become a >> “provider” > > It's hard for me to evaluate this idea. Intuitively, it doesn't seem ideal. > In general, I'm not very fond of $_GET/$_POST. But on the other hand, why > not? This needs some consideration. > >> allow to very easily to turn i.e. php-fpm into a fully asynchronous >> application server, >> where each request is started in the same thread (or in N threads in an M-N >> M>N >> execution model) but its global state is entirely isolated between fibers. > I haven’t thought about this possibility. But wouldn’t this break the FCGI > contract? I see no reason why it should break the contract, if implemented by isolating the global state of each fiber, it can be treated as a mere implementation detail of the (eventually new) SAPI. Regards, Daniil Gentili — Daniil Gentili - Senior software engineer Portfolio: https://daniil.it <https://daniil.it/>Telegram: https://t.me/danogentili