On Fri, Jan 5, 2024 at 2:56 AM Daniil Gentili <daniil.gent...@gmail.com> wrote:
>
> Hi,
>
> I've been lurking around in the discussion for a while, and I'd like to chime 
> in now since the main, glaring issue with this proposal has only been 
> explicitly mentioned by Rowan Tomminis, with that subthread quickly 
> degenerating with misguided replies.
>
> PHP as a language absolutely needs a persistent worker mode like in all other 
> backend languages, which will greatly improve performance by avoiding all 
> overhead related to request initialization.
>
> However, the current proposal of adding support for worker mode SAPIs based 
> on the usual PHP superglobals is fundamentally incompatible with concurrency 
> (aka async, aka swoole, amphp, fiber-based concurrent runtimes in general), 
> and I believe would steer the PHP ecosystem in the wrong direction.
>
> Rowan already offered a nice example of why earlier in the thread, but as an 
> explanation to those that may not have understood that, so I whipped up a 
> briefer at https://gist.github.com/danog/f0e9103e6a7e1bcec1b92c411a3c4607
>
>
>
> So no, unlike what I've read in another message here, "The nodejs curse [...] 
> where async and co may actually slow down your whole node." is simply false 
> for the majority of modern usecases, because the majority of modern 
> applications is I/O-intensive, not CPU-intensive.
>
>
> Implementing a worker API the way it is proposed is fundamentally 
> incompatible with userland cooperative schedulers aka event loops like amphp 
> or reactphp, and each request would be handled, just like in php-fpm, in a 
> separate OS thread, not in a much more efficient userland thread.
>
> Cooperative schedulers implemented outside of PHP in the form of an extension 
> such as swoole would also not be able to easily make use of the initially 
> proposed API to handle requests in separate coroutines, even if the 
> handle_request function was intercepted by swoole to return control to the 
> swoole event loop (which would already make it superfluous as a PHP API), 
> since the proposal involves messing around with the usual superglobals, which 
> as mentioned by Rowan would require manual copying of the superglobals before 
> using them in a newly spawned swoole coroutine.
>
> I believe that a much, much better way of implementing a worker mode in PHP 
> core would be to provide a fiber-aware function/static method returning, upon 
> receiving a request, a class implementing the PSR-7 RequestInterface.
>
> Fiber-aware here means that the function should behave in a way similar to 
> how all native PHP I/O functions should behave in an upcoming Native Event 
> Loop RFC I'm planning to make.
>
> The idea here is to make all I/O related functions, including this new 
> wait_request function, completely async in a manner that is compatible with 
> fibers and pure PHP event loops like amphp.
>
> It would essentially work as follows: an event loop like uv is integrated 
> within PHP itself at least for the native stream wrapper (I.e. all filesystem 
> and network functions, file_get_contents and so on).
> Extensions will be provided an API to interact with the event loop.
>
> I'm currently finalizing the details, and might probably make a first RFC in 
> the coming weeks, suffice to say that everything will work in a manner very 
> similar to how async works in both the ext-pq and php-tokio extensions, 
> albeit with fiber integration: a separate event loop (let's call it native) 
> is started in another OS thread (like with ext-pq or php-tokio, WITHOUT the 
> need for ZTS, as no PHP data structures are modified in the native event 
> loop), events are sent via a single descriptor from the native event loop to 
> the userland event loop (I.e. amphp).
>
> If running inside a fiber, tasks are queued to the native event loop and the 
> fiber is suspended with a NativeSuspension, then resumed by the userland 
> event loop.
>
> If not running inside a fiber, tasks are queued to the native event loop and 
> control is returned to the userland event loop.
>
> Essentially, my proposal is almost exactly what is already being done in 
> https://github.com/danog/php-tokio, but library-agonstic and implemented 
> inside of PHP itself, perhaps even using Rust and tokio as well.
>
> I feel that the current direction of the discussion of PHP worker modes is 
> wrong, as it is mostly ignoring the presence of a perfectly usable 
> concurrency API in PHP (fibers): this has potential to cause a big split in 
> the PHP ecosystem, unless PHP finally fully embraces concurrency and async 
> with a native event loop proposal, like the one I intend to present soon.
>
> I hope that further discussion of a worker mode continues with an eye to the 
> future with native concurrency :)
>
> Regards,
> Daniil Gentili.
>
> P. S. Just in case to avoid confusion for some, frankenphp does NOT add 
> native concurrency to php using goroutines, as control to the go event loop 
> is only returned when calling functions like header or echo which cause a 
> suspension of the goroutine because an I/O operation is made on the go side, 
> but
>
> 1) That's incompatible with fibers, and not just because of the minor go 
> compatibility bug which is being fixed, but because the go event loop is not 
> integrated with any php event loop, and thus does not know to return control 
> to any eventual php fiber when needed, and will just block all PHP fibers 
> until that single go I/O operation is done (unlike in php-tokio, where the 
> rust tokio event loop is fully integrated with the php event loop (currently 
> just revolt)).
>
> 2) It doesn't even replace the native stream wrapper with go-backed async I/O 
> like swoole does (though both this and php event loop integration like in 
> php-tokio is fully possible in frankenphp with a bit of work, I could 
> actually lend a hand if needed...)

Hey Daniil,

I already said this, but to reiterate: I, personally, hear what you
are saying and largely agree with you; however, before we can really
have any kind of discussion on concurrent servers, we HAVE to address
the underlying issues that are missing from PHP. In PHP-src, there are
no such things as request objects. There are no such things as event
loops. There are fibers, but absolutely no std-library i/o functions
are using them, making it pointless to build on fibers except when
using user-land libraries that reimplemented everything (like amphp)
in pure PHP or an extension like swoole.

That is the unfortunate point we are at and it doesn't make sense to
address concurrent servers at this moment, or passing request objects.
We have a long way to go before those will be real things that we can
have a proper conversation about in the context of php-src.

Robert Landers
Software Engineer
Utrecht NL

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to