On 31 December 2023 08:31:16 GMT, "Kévin Dunglas" <ke...@dunglas.fr> wrote:
>This new function is intended for SAPIs. Swoole was given as an example of
>worker mode, but it isn't a SAPI. AFAIK, it doesn't use the SAPI
>infrastructure provided by PHP.
>The scope of my proposal is only to provide a new feature in the SAPI
>infrastructure to build worker modes to handle HTTP requests, not to deal
>with non-SAPI engines.

One of the advantages you suggested of your proposal is that users would have a 
consistent way to write worker scripts. To achieve that, you want a *design* 
that can be adopted by as many implementations as possible, regardless of how 
they implement it. Providing helper infrastructure for that design is a 
secondary concern - as you admit, the actual code you're proposing to add is 
quite short.


>That being said, I don't understand what would prevent Swoole from
>implementing the proposed API

Then one of us is missing something very fundamental. As I understand it, 
Swoole's model is similar to that popularised by node.js: a single thread 
processes multiple incoming requests concurrently, using asynchronous I/O. For 
instance, a thread might run the following:

01 Request A received
02 Request A input validated
03 Request A sends async query to DB
04 Request A hands control to event loop while it awaits result
05 Request B received
06 Request B sends async HTTP call to some API
07 Request B awaits result
08 Request A resumed with DB result
09 Request A formats and returns response
10 Request A complete
11 Request B resumed
12 Request B fornats and returns response

Each request has its own call stack, started by a different call to the 
registered event handler, but any global state is shared between them - there 
is no actual threading going on, so no partitioned memory.

If requests are communicated by setting up superglobals, that will happen at 
step 01 and again at step 05. If you try to read from them at step 09, you 
would see them populated with information about request B, but you're trying to 
handle request A.

It would be possible to work around that by placing large warnings to users not 
to read superglobals after any async call - basically forcing them to create 
scoped copies to pass around. But the worse problem is output: if step 09 and 
step 12 both just use "echo", how do you track which output needs to go to 
which network connection? You can't just set up an output buffer, because 
that's global state shared by both call stacks. You have to put *something* 
into the scope of the call stack - a callback to write output, an expected 
return value, etc.

Asynchronous code ends up somewhat resembling functional programming: 
everything you want to have side effects on needs to be passed around as 
parameters and return values, because the only thing isolated between requests 
is local variable scope.
 
Regards,

-- 
Rowan Tommins
[IMSoP]

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

Reply via email to