Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Alexander Pravdin
>
> So you want to introduce a SAPI that doesn't work with any of the existing
> HTTP solutions people use that only supports HTTP requests? Or am I
> misunderstanding something?
>
> This sounds a bit like you want to merge in a tool that is designed for
> your personal product directly into core. FrankenPHP may be incredible and
> awesome, but the world runs on Apache and Nginx for HTTP requests.
>
>
To be honest, after trying RoadRunner (an alternative to FrankenPHP), I'm
using it for all my projects if the framework and packages have no issues
with this execution model. Only old codebases with extensive usage of
global variables and stateful services are at risk. If you stick with
readonly classes and follow best DI practices, there will be minimum to no
issues. Symfomy is actively propagating safe coding styles. So from my POV
it is not a problem that a new execution model will be supported. If your
code is not compatible - then this is your problem. It is normal that some
code may not work properly in different modes. The fact that the world is
running on Apache and Nginx doesn't mean this will be forever with no
alternatives. The fact that there are multiple projects with the same goal
shows that there is a big demand for PHP speedup. And there are no visible
alternatives except a worker mode. IMO.


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Pierre Joye
Hello,

On Tue, Dec 26, 2023, 1:56 AM Jordan LeDoux  wrote:

>
> So you want to introduce a SAPI that doesn't work with any of the existing
> HTTP solutions people use that only supports HTTP requests? Or am I
> misunderstanding something?
>
> This sounds a bit like you want to merge in a tool that is designed for
> your personal product directly into core. FrankenPHP may be incredible and
> awesome, but the world runs on Apache and Nginx for HTTP requests.



The world was running on cgi when php was created and a few years after.
Then the world was running on threads/apache. Then it ran in fcgi and
finally fcgi fpm for the last few years.

Other languages support this since quite some time. Projects like reactphp,
swoole and the likes provide userland versions of it and the benefits are
clear. They even worked together recently to get a common core. Many
(large) projects out there already support FrankenPHP, the needs are there.

FrankenPhp and a worker mode go beyond the classical php usages we had.
Desktop applications or IoT are getting more common (see laravel's
nativephp f.e.). I have done something similar for one of our products
using embedded sapi but how it is done using frankenphp would be an order
of magnitude better.

Having the complex parts in the core us a good start to experiment, adapt.
Later a core sapi may be added, we cannot know without trying and let the
community uses it.

best,
Pierre


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Lanre Waju
Why not just build this into the embed sapi instead? since its only for 
third party sapis?


On 2023-12-23 1:34 p.m., Kévin Dunglas wrote:

Hello and Merry Christmas!

One of the main features of FrankenPHP is its worker mode, which lets you
keep a PHP application in memory to handle multiple HTTP requests.

Worker modes are becoming increasingly popular in the PHP world. Symfony
(Runtime Component), Laravel (Octane), and many projects based on these
frameworks (API Platform, Sulu...) now support a worker mode.

In addition to FrankenPHP, projects such as RoadRunner and Swoole provide
engines supporting worker modes.

According to benchmarks, worker modes can improve the performance of PHP
applications by up to 15 times.
In addition to FrankenPHP, which is basically a SAPI for Go's integrated
web server, a new generation of SAPIs is currently under development.
Several SAPIs written in Rust (including one by the RoadRunner team) are
currently under development.

These SAPIs, along with existing SAPIs, could benefit from a shared
infrastructure to build worker modes.



The FrankenPHP code is written and should be easy to move around in PHP
itself, to enable other SAPIs to use it.

In addition to sharing code, maintenance, performance optimization, etc.,
the existence of a common infrastructure would standardize the way worker
scripts are created and provide a high-level PHP API for writing worker
scripts that work with all SAPIs that rely on this new feature.

SAPIs will still have to handle fetching requests from the web server and
pausing the worker to wait for new requests (in FrankenPHP, we use
GoRoutines for this, in Rust or C, other primitives will have to be used),
but almost everything else could be shared.

For reference, here's the FrankenPHP code I propose to integrate into
libphp: https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L245

The public API is documented here:
https://frankenphp.dev/docs/worker/#custom-apps

I'd like to hear what the community thinks about this. Would you be
interested in this functionality in PHP? Should I work on an RFC?

If there's interest, I can work on a patch.

Cheers,


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



Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Jakub Zelenka
Hi,

On Tue, Dec 26, 2023 at 12:09 AM Robert Landers 
wrote:

> Hi Jakub,
>
> > I have been thinking about something similar for FPM and if you had some
> > sort pool manager process, you could maybe do some sort of initial
> > execution but then it gets really tricky especially with sharing
> resources
> > and managing connections. I think it would be a big can of worms so I
> don't
> > think this is going to happen anytime soon.
>
> It's already happening. Most libraries (particularly popular ones in
> the Symfony/Laravel world) already support most of this
> out-of-the-box. I love stateless servers, but sometimes a stateful
> server is better. What is really nice about worker mode is that you
> can actually have a PHP-native in-memory database that only exists for
> as long as the worker is running (I do this for some unit tests).
>
>
This was just about FPM. What I meant that this is not going to be
supported by FPM anytime soon if ever.


> > I could imaging that there will
> > be similar issues for Apache prefork which is likely the most used MPM
> for
> > legacy apps. Effectively it means that this function won't be working on
> > most installations as two of the likely most used SAPI's won't support
> it.
> > I think it should be pretty clear from the beginning.
>
> Most people are familiar with fastcgi_finish_request() and there are
> some built-in SAPI's that don't support it. I don't think that just
> because it won't start out with full support, it should be discarded.
>
>
I didn't mean that it shouldn't be added. It should just be clear from the
beginning that this will be for limited set of SAPIs.


> > It would be also good to put together some base design PR for this as
> > currently SAPI common functions are implemented separately in each SAPI
> > (e.g. apache_request_headers). From the linked functionality, it is is
> not
> > a big amount of code and seems somehow specific to the FrankenPHP so why
> > couldn't each SAPI just implement this function separately? I know that
> > this is not ideal but it's what is already used for
> apache_request_headers.
> > I think otherwise you would need some hooking mechanism that should have
> > some default (which would probably just throw exception) because it is
> not
> > going to be implemented by all SAPI's. I think it would be really good if
> > you could provide more details about planned implementation for this.
>
> Most (all?) modern SAPI (lightspeed, roadrunner, etc) implements
> fastcgi_finish_request(), even if no fastcgi is involved, simply
> because of backward compatibility. It'd be great to actually bikeshed
> a decent name and syntax/semantics before something popular comes
> along and forces us all to use frankenphp_handle_request() or
> something, simply because of backward compatibility.
>

I agree that coming up with some sensible name and API would be a good
think even though it will have limited use in core. And if it gives us some
coverage of embed SAPI (libphp), then it's even better.

Cheers

Jakub


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Jakub Zelenka
On Mon, Dec 25, 2023 at 7:06 PM Kévin Dunglas  wrote:

>
> On Mon, Dec 25, 2023 at 6:30 PM Jakub Zelenka  wrote:
>
>>
>>
>> On Mon, Dec 25, 2023 at 12:34 PM Kévin Dunglas  wrote:
>>
>>> On Sun, Dec 24, 2023 at 4:21 PM Larry Garfield 
>>> wrote:
>>>
>>> In practice, I want to understand the implications for user-space code.
>>> > Does this mean FPM could be configured in a way to execute a file like
>>> that
>>> > shown in the docs page above?  Or would it only work with third party
>>> SAPIs
>>> > like FrankenPHP?
>>>
>>>
>>> In theory, PHP-FPM and the Apache module could - like all other SAPIs -
>>> be
>>> enhanced to add a worker mode operating as described in the FrankenPHP
>>> doc
>>> thanks to these new primitives.
>>>
>>
>> I have been thinking about something similar for FPM and if you had some
>> sort pool manager process, you could maybe do some sort of initial
>> execution but then it gets really tricky especially with sharing resources
>> and managing connections. I think it would be a big can of worms so I don't
>> think this is going to happen anytime soon. I could imaging that there will
>> be similar issues for Apache prefork which is likely the most used MPM for
>> legacy apps. Effectively it means that this function won't be working on
>> most installations as two of the likely most used SAPI's won't support it.
>> I think it should be pretty clear from the beginning.
>>
>>
>>> However, I suggest doing this as a second step, because as described in
>>> my
>>> first post, it will still be the responsibility of each SAPI to manage
>>> long-running processes and communication with them. This is simple to do
>>> with Go's GoRoutine and Rust's asynchronous runtimes such as Tokio, it's
>>> definitely more difficult in cross-platform C. I suggest starting by
>>> adding
>>> the primitives to libphp, then we'll see how to exploit them (and whether
>>> it's worthwhile) in the built-in SAPIs.
>>>
>>
>> The problem with this is that we would add some code that won't be used
>> by any of the built in SAPI which means that that we won't be able to have
>> automated tests for this. So the minimum should be to have at least one
>> core SAPI supporting this new functionality. I wouldn't mind if it's just a
>> SAPI for testing purpose which might be actually useful for testing embed
>> SAPI code. I think that should be a requirement for accepting a PR
>> introducing this.
>>
>> It would be also good to put together some base design PR for this as
>> currently SAPI common functions are implemented separately in each SAPI
>> (e.g. apache_request_headers). From the linked functionality, it is is not
>> a big amount of code and seems somehow specific to the FrankenPHP so why
>> couldn't each SAPI just implement this function separately? I know that
>> this is not ideal but it's what is already used for apache_request_headers.
>> I think otherwise you would need some hooking mechanism that should have
>> some default (which would probably just throw exception) because it is not
>> going to be implemented by all SAPI's. I think it would be really good if
>> you could provide more details about planned implementation for this.
>>
>>
>>> I personally have less interest in working on FPM/CGI/mod_php as the
>>> other
>>> possibilities offered by modern SAPIs like FrankenPHP are more important
>>> (better deployment experience as you have a single static binary or
>>> Docker
>>> image, Early Hints support, high-quality native HTTP/3 server etc)
>>>
>>>
>> Except that those are all threaded SAPIs so they offer less separation
>> and protection against application crashes in addition to the fact that
>> thread management in PHP still has got its own issues. They are certainly
>> some advantages especially for thin services but if you have huge monolith
>> codebase like some big CMS and other projects, then I would probably stick
>> with process separation model.
>>
>> Cheers
>>
>> Jakub
>>
>
> Sure, the main targets are new SAPIs like FrankenPHP and the one in Rust
> developed by the RoadRunner team. I thought it was clear in my previous
> messages but I'll be glad to make it bold in the RFC.
>

The way how I read was that this would be eventually supported by all SAPIs
which I think is not likely going to be the case.


> Automated tests (likely through a test SAPI) will definitely be needed.
> Throwing if the current SAPI doesn't support (yet) the new userland
> function looks sensitive.
>
>
+1


> Couldn't this shared code be put in "main", as it could (theoretically, I
> agree that it will be hard to do for existing core SAPIs) be used by all
> SAPIs?
>

The main does not have a module but it could be probably added to standard
ext like it's the case for other functionality related to main.

Cheers

Jakub


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Robert Landers
Hi Jakub,

> I have been thinking about something similar for FPM and if you had some
> sort pool manager process, you could maybe do some sort of initial
> execution but then it gets really tricky especially with sharing resources
> and managing connections. I think it would be a big can of worms so I don't
> think this is going to happen anytime soon.

It's already happening. Most libraries (particularly popular ones in
the Symfony/Laravel world) already support most of this
out-of-the-box. I love stateless servers, but sometimes a stateful
server is better. What is really nice about worker mode is that you
can actually have a PHP-native in-memory database that only exists for
as long as the worker is running (I do this for some unit tests).

> I could imaging that there will
> be similar issues for Apache prefork which is likely the most used MPM for
> legacy apps. Effectively it means that this function won't be working on
> most installations as two of the likely most used SAPI's won't support it.
> I think it should be pretty clear from the beginning.

Most people are familiar with fastcgi_finish_request() and there are
some built-in SAPI's that don't support it. I don't think that just
because it won't start out with full support, it should be discarded.

> It would be also good to put together some base design PR for this as
> currently SAPI common functions are implemented separately in each SAPI
> (e.g. apache_request_headers). From the linked functionality, it is is not
> a big amount of code and seems somehow specific to the FrankenPHP so why
> couldn't each SAPI just implement this function separately? I know that
> this is not ideal but it's what is already used for apache_request_headers.
> I think otherwise you would need some hooking mechanism that should have
> some default (which would probably just throw exception) because it is not
> going to be implemented by all SAPI's. I think it would be really good if
> you could provide more details about planned implementation for this.

Most (all?) modern SAPI (lightspeed, roadrunner, etc) implements
fastcgi_finish_request(), even if no fastcgi is involved, simply
because of backward compatibility. It'd be great to actually bikeshed
a decent name and syntax/semantics before something popular comes
along and forces us all to use frankenphp_handle_request() or
something, simply because of backward compatibility.

I think this functionality unlocks some really cool potential powers
(in-memory databases for development, connection pooling without an
extension, etc) and it's worth at least seriously considering
implementing it in core.

- Rob

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



Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Kévin Dunglas
On Mon, Dec 25, 2023 at 7:56 PM Jordan LeDoux 
wrote:

>
>
> On Mon, Dec 25, 2023 at 8:19 AM Kévin Dunglas  wrote:
>
>>
>> On Sun, Dec 24, 2023 at 10:44 PM Jordan LeDoux 
>> wrote:
>>
>>>
>>>
>>> On Sat, Dec 23, 2023 at 12:34 PM Kévin Dunglas  wrote:
>>>
 Hello and Merry Christmas!

 One of the main features of FrankenPHP is its worker mode, which lets
 you
 keep a PHP application in memory to handle multiple HTTP requests.

 Worker modes are becoming increasingly popular in the PHP world. Symfony
 (Runtime Component), Laravel (Octane), and many projects based on these
 frameworks (API Platform, Sulu...) now support a worker mode.

 In addition to FrankenPHP, projects such as RoadRunner and Swoole
 provide
 engines supporting worker modes.

 According to benchmarks, worker modes can improve the performance of PHP
 applications by up to 15 times.
 In addition to FrankenPHP, which is basically a SAPI for Go's integrated
 web server, a new generation of SAPIs is currently under development.
 Several SAPIs written in Rust (including one by the RoadRunner team) are
 currently under development.

 These SAPIs, along with existing SAPIs, could benefit from a shared
 infrastructure to build worker modes.



 The FrankenPHP code is written and should be easy to move around in PHP
 itself, to enable other SAPIs to use it.

 In addition to sharing code, maintenance, performance optimization,
 etc.,
 the existence of a common infrastructure would standardize the way
 worker
 scripts are created and provide a high-level PHP API for writing worker
 scripts that work with all SAPIs that rely on this new feature.

 SAPIs will still have to handle fetching requests from the web server
 and
 pausing the worker to wait for new requests (in FrankenPHP, we use
 GoRoutines for this, in Rust or C, other primitives will have to be
 used),
 but almost everything else could be shared.

 For reference, here's the FrankenPHP code I propose to integrate into
 libphp:
 https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L245

 The public API is documented here:
 https://frankenphp.dev/docs/worker/#custom-apps

 I'd like to hear what the community thinks about this. Would you be
 interested in this functionality in PHP? Should I work on an RFC?

 If there's interest, I can work on a patch.

 Cheers,
 --
 Kévin Dunglas

>>>
>>> Much like Larry, I'm curious what sort of scope you imagine for this.
>>> Are you imagining something that is geared specifically towards HTTP
>>> requests, or would this be a more generic "PHP Application Worker" that
>>> might be spawned to handle other types of applications? Could we have a
>>> worker listen to a specific port and respond to or handle all requests on
>>> that port/device?
>>>
>>> Jordan
>>>
>>
>> Ho Jordan,
>>
>> Yes, the scope I imagine is geared specifically towards HTTP requests.
>> Something more generic than common primitives for SAPIs and a shared public
>> API to handle HTTP requests with a long-running PHP worker script will be
>> hard to do outside of SAPIs because they depend on a lot of external
>> concerns such as the programming language the SAPI is using.
>>
>
> So you want to introduce a SAPI that doesn't work with any of the existing
> HTTP solutions people use that only supports HTTP requests? Or am I
> misunderstanding something?
>
> This sounds a bit like you want to merge in a tool that is designed for
> your personal product directly into core. FrankenPHP may be incredible and
> awesome, but the world runs on Apache and Nginx for HTTP requests.
>
> Jordan
>

As explained in the initial message and in my reply to Jakub, the main
targets are emerging SAPIs. We have no interest (quite the contrary) in
moving this code from FrankenPHP to PHP core (harder maintenance, slower
iterations as more collaboration will be involved...), but I do think that
having a "standard" and shared infrastructure and API for worker modes
between new generation SAPIs will be beneficial to the community as a whole
(no need - as at present - to write a different worker script for each
engine having a worker mode, sharing of optimizations, security patches
etc...).

We're talking roughly about a C function of a few dozen lines, not
something very big.


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Kévin Dunglas
On Mon, Dec 25, 2023 at 6:30 PM Jakub Zelenka  wrote:

>
>
> On Mon, Dec 25, 2023 at 12:34 PM Kévin Dunglas  wrote:
>
>> On Sun, Dec 24, 2023 at 4:21 PM Larry Garfield 
>> wrote:
>>
>> In practice, I want to understand the implications for user-space code.
>> > Does this mean FPM could be configured in a way to execute a file like
>> that
>> > shown in the docs page above?  Or would it only work with third party
>> SAPIs
>> > like FrankenPHP?
>>
>>
>> In theory, PHP-FPM and the Apache module could - like all other SAPIs - be
>> enhanced to add a worker mode operating as described in the FrankenPHP doc
>> thanks to these new primitives.
>>
>
> I have been thinking about something similar for FPM and if you had some
> sort pool manager process, you could maybe do some sort of initial
> execution but then it gets really tricky especially with sharing resources
> and managing connections. I think it would be a big can of worms so I don't
> think this is going to happen anytime soon. I could imaging that there will
> be similar issues for Apache prefork which is likely the most used MPM for
> legacy apps. Effectively it means that this function won't be working on
> most installations as two of the likely most used SAPI's won't support it.
> I think it should be pretty clear from the beginning.
>
>
>> However, I suggest doing this as a second step, because as described in my
>> first post, it will still be the responsibility of each SAPI to manage
>> long-running processes and communication with them. This is simple to do
>> with Go's GoRoutine and Rust's asynchronous runtimes such as Tokio, it's
>> definitely more difficult in cross-platform C. I suggest starting by
>> adding
>> the primitives to libphp, then we'll see how to exploit them (and whether
>> it's worthwhile) in the built-in SAPIs.
>>
>
> The problem with this is that we would add some code that won't be used by
> any of the built in SAPI which means that that we won't be able to have
> automated tests for this. So the minimum should be to have at least one
> core SAPI supporting this new functionality. I wouldn't mind if it's just a
> SAPI for testing purpose which might be actually useful for testing embed
> SAPI code. I think that should be a requirement for accepting a PR
> introducing this.
>
> It would be also good to put together some base design PR for this as
> currently SAPI common functions are implemented separately in each SAPI
> (e.g. apache_request_headers). From the linked functionality, it is is not
> a big amount of code and seems somehow specific to the FrankenPHP so why
> couldn't each SAPI just implement this function separately? I know that
> this is not ideal but it's what is already used for apache_request_headers.
> I think otherwise you would need some hooking mechanism that should have
> some default (which would probably just throw exception) because it is not
> going to be implemented by all SAPI's. I think it would be really good if
> you could provide more details about planned implementation for this.
>
>
>> I personally have less interest in working on FPM/CGI/mod_php as the other
>> possibilities offered by modern SAPIs like FrankenPHP are more important
>> (better deployment experience as you have a single static binary or Docker
>> image, Early Hints support, high-quality native HTTP/3 server etc)
>>
>>
> Except that those are all threaded SAPIs so they offer less separation and
> protection against application crashes in addition to the fact that thread
> management in PHP still has got its own issues. They are certainly some
> advantages especially for thin services but if you have huge monolith
> codebase like some big CMS and other projects, then I would probably stick
> with process separation model.
>
> Cheers
>
> Jakub
>

Sure, the main targets are new SAPIs like FrankenPHP and the one in Rust
developed by the RoadRunner team. I thought it was clear in my previous
messages but I'll be glad to make it bold in the RFC.
Automated tests (likely through a test SAPI) will definitely be needed.
Throwing if the current SAPI doesn't support (yet) the new userland
function looks sensitive.

Couldn't this shared code be put in "main", as it could (theoretically, I
agree that it will be hard to do for existing core SAPIs) be used by all
SAPIs?


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Jordan LeDoux
On Mon, Dec 25, 2023 at 8:19 AM Kévin Dunglas  wrote:

>
> On Sun, Dec 24, 2023 at 10:44 PM Jordan LeDoux 
> wrote:
>
>>
>>
>> On Sat, Dec 23, 2023 at 12:34 PM Kévin Dunglas  wrote:
>>
>>> Hello and Merry Christmas!
>>>
>>> One of the main features of FrankenPHP is its worker mode, which lets you
>>> keep a PHP application in memory to handle multiple HTTP requests.
>>>
>>> Worker modes are becoming increasingly popular in the PHP world. Symfony
>>> (Runtime Component), Laravel (Octane), and many projects based on these
>>> frameworks (API Platform, Sulu...) now support a worker mode.
>>>
>>> In addition to FrankenPHP, projects such as RoadRunner and Swoole provide
>>> engines supporting worker modes.
>>>
>>> According to benchmarks, worker modes can improve the performance of PHP
>>> applications by up to 15 times.
>>> In addition to FrankenPHP, which is basically a SAPI for Go's integrated
>>> web server, a new generation of SAPIs is currently under development.
>>> Several SAPIs written in Rust (including one by the RoadRunner team) are
>>> currently under development.
>>>
>>> These SAPIs, along with existing SAPIs, could benefit from a shared
>>> infrastructure to build worker modes.
>>>
>>>
>>>
>>> The FrankenPHP code is written and should be easy to move around in PHP
>>> itself, to enable other SAPIs to use it.
>>>
>>> In addition to sharing code, maintenance, performance optimization, etc.,
>>> the existence of a common infrastructure would standardize the way worker
>>> scripts are created and provide a high-level PHP API for writing worker
>>> scripts that work with all SAPIs that rely on this new feature.
>>>
>>> SAPIs will still have to handle fetching requests from the web server and
>>> pausing the worker to wait for new requests (in FrankenPHP, we use
>>> GoRoutines for this, in Rust or C, other primitives will have to be
>>> used),
>>> but almost everything else could be shared.
>>>
>>> For reference, here's the FrankenPHP code I propose to integrate into
>>> libphp:
>>> https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L245
>>>
>>> The public API is documented here:
>>> https://frankenphp.dev/docs/worker/#custom-apps
>>>
>>> I'd like to hear what the community thinks about this. Would you be
>>> interested in this functionality in PHP? Should I work on an RFC?
>>>
>>> If there's interest, I can work on a patch.
>>>
>>> Cheers,
>>> --
>>> Kévin Dunglas
>>>
>>
>> Much like Larry, I'm curious what sort of scope you imagine for this. Are
>> you imagining something that is geared specifically towards HTTP requests,
>> or would this be a more generic "PHP Application Worker" that might be
>> spawned to handle other types of applications? Could we have a worker
>> listen to a specific port and respond to or handle all requests on that
>> port/device?
>>
>> Jordan
>>
>
> Ho Jordan,
>
> Yes, the scope I imagine is geared specifically towards HTTP requests.
> Something more generic than common primitives for SAPIs and a shared public
> API to handle HTTP requests with a long-running PHP worker script will be
> hard to do outside of SAPIs because they depend on a lot of external
> concerns such as the programming language the SAPI is using.
>

So you want to introduce a SAPI that doesn't work with any of the existing
HTTP solutions people use that only supports HTTP requests? Or am I
misunderstanding something?

This sounds a bit like you want to merge in a tool that is designed for
your personal product directly into core. FrankenPHP may be incredible and
awesome, but the world runs on Apache and Nginx for HTTP requests.

Jordan


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Jakub Zelenka
On Mon, Dec 25, 2023 at 12:34 PM Kévin Dunglas  wrote:

> On Sun, Dec 24, 2023 at 4:21 PM Larry Garfield 
> wrote:
>
> In practice, I want to understand the implications for user-space code.
> > Does this mean FPM could be configured in a way to execute a file like
> that
> > shown in the docs page above?  Or would it only work with third party
> SAPIs
> > like FrankenPHP?
>
>
> In theory, PHP-FPM and the Apache module could - like all other SAPIs - be
> enhanced to add a worker mode operating as described in the FrankenPHP doc
> thanks to these new primitives.
>

I have been thinking about something similar for FPM and if you had some
sort pool manager process, you could maybe do some sort of initial
execution but then it gets really tricky especially with sharing resources
and managing connections. I think it would be a big can of worms so I don't
think this is going to happen anytime soon. I could imaging that there will
be similar issues for Apache prefork which is likely the most used MPM for
legacy apps. Effectively it means that this function won't be working on
most installations as two of the likely most used SAPI's won't support it.
I think it should be pretty clear from the beginning.


> However, I suggest doing this as a second step, because as described in my
> first post, it will still be the responsibility of each SAPI to manage
> long-running processes and communication with them. This is simple to do
> with Go's GoRoutine and Rust's asynchronous runtimes such as Tokio, it's
> definitely more difficult in cross-platform C. I suggest starting by adding
> the primitives to libphp, then we'll see how to exploit them (and whether
> it's worthwhile) in the built-in SAPIs.
>

The problem with this is that we would add some code that won't be used by
any of the built in SAPI which means that that we won't be able to have
automated tests for this. So the minimum should be to have at least one
core SAPI supporting this new functionality. I wouldn't mind if it's just a
SAPI for testing purpose which might be actually useful for testing embed
SAPI code. I think that should be a requirement for accepting a PR
introducing this.

It would be also good to put together some base design PR for this as
currently SAPI common functions are implemented separately in each SAPI
(e.g. apache_request_headers). From the linked functionality, it is is not
a big amount of code and seems somehow specific to the FrankenPHP so why
couldn't each SAPI just implement this function separately? I know that
this is not ideal but it's what is already used for apache_request_headers.
I think otherwise you would need some hooking mechanism that should have
some default (which would probably just throw exception) because it is not
going to be implemented by all SAPI's. I think it would be really good if
you could provide more details about planned implementation for this.


> I personally have less interest in working on FPM/CGI/mod_php as the other
> possibilities offered by modern SAPIs like FrankenPHP are more important
> (better deployment experience as you have a single static binary or Docker
> image, Early Hints support, high-quality native HTTP/3 server etc)
>
>
Except that those are all threaded SAPIs so they offer less separation and
protection against application crashes in addition to the fact that thread
management in PHP still has got its own issues. They are certainly some
advantages especially for thin services but if you have huge monolith
codebase like some big CMS and other projects, then I would probably stick
with process separation model.

Cheers

Jakub


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Kévin Dunglas
> Forgive my ignorance, but why no connection?  You mean the
> pre-worker-start part needs to avoid an SQL connection?  Why is that?  That
> would be something that needs to be super-well documented, and possibly
> some guards in place to prevent it, if there's no good way around it.
> (This is the sort of detail I'm thinking of, where I just don't know the
> implications but want to think through them as much as possible in advance,
> so that it can be "safe by design.")
>

Sorry, I made a typo. I mean "libraries must ensure that the connection
**is** active" (if the connection timeout has been reached, the library
must reconnect).
Your worker script will be long-running code, as in Java, Go, etc. So if it
depends on external services, it must check that the connection is still
active, and reconnect if necessary.
This is the default in most languages, but not in PHP (yet).

Do you have an intent or expectation of a worker-style SAPI being shipped
> with PHP itself, or for that to remain the domain of third parties?
>

As I tried to explain in my previous message, this could be nice, and
possible, but I don't plan to do it myself for now :)


> I mean more what implications would there be on how user-space code is
> written to be worker-SAPI-friendly.  (The SQL connection comment above, for
> example.)  I have not worked with any of the worker-ish tools so far
> myself, so other than "you'll need an alternate index.php for that", I
> don't have a good sense of what else I'd want to do differently to play
> nice with Franken and Friends.
>

As far as I know, there are no other implications than memory (and other
resources) leaks (https://laravel.com/docs/10.x/octane#managing-memory-leaks)
and timeout handling.


> The idea of combining fiber-based code with supported worker-mode runners
> sounds like a ridiculously cool future for PHP, but I don't know how windy
> that path is. :-)
>

That already works if you use FrankenPHP! Joe also experimented
successfully using the parallel extension instead of Fibers:
https://twitter.com/krakjoe/status/1587234661696245760


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Larry Garfield
On Mon, Dec 25, 2023, at 6:34 AM, Kévin Dunglas wrote:

> However, I suggest doing this as a second step, because as described in 
> my first post, it will still be the responsibility of each SAPI to 
> manage long-running processes and communication with them. This is 
> simple to do with Go's GoRoutine and Rust's asynchronous runtimes such 
> as Tokio, it's definitely more difficult in cross-platform C. I suggest 
> starting by adding the primitives to libphp, then we'll see how to 
> exploit them (and whether it's worthwhile) in the built-in SAPIs.
> I personally have less interest in working on FPM/CGI/mod_php as the 
> other possibilities offered by modern SAPIs like FrankenPHP are more 
> important (better deployment experience as you have a single static 
> binary or Docker image, Early Hints support, high-quality native HTTP/3 
> server etc), but I'd be happy to help if anyone wants to update these 
> SAPIs.

>> To what extent would user-space code run this way have to think about 
>> concurrency, shared memory, persistent SQL connections, etc?  Does it have 
>> any implications for fiber-using async code?
>
> Regarding concurrency, it doesn't change much (it's similar to existing 
> SAPI). Regarding memory and SQL connections, extra care is required. 
> Memory leaks (and other kinds of leaks) should be avoided (or workers 
> should restart from time to time, which is obviously a poorer 
> solution). Libraries maintaining SQL connections such as Doctrine or 
> Eloquent must ensure that the connection isn't active.

Forgive my ignorance, but why no connection?  You mean the pre-worker-start 
part needs to avoid an SQL connection?  Why is that?  That would be something 
that needs to be super-well documented, and possibly some guards in place to 
prevent it, if there's no good way around it.  (This is the sort of detail I'm 
thinking of, where I just don't know the implications but want to think through 
them as much as possible in advance, so that it can be "safe by design.")

> Fibers work as expected. There is a small limitation when using them 
> with Go (that is being tracked in the Go runtime, 
> https://frankenphp.dev/docs/known-issues/#fibers), but it's not related 
> to the C code of the worker mode, and this limitation shouldn't exist 
> for SAPIs not written in Go.
> 
>> Depending on the details, this could be like fibers but for 3rd party SAPIs 
>> (something about 4 people in the world actually care about directly, 
>> everyone else just uses Revolt, Amp, or React, but mostly it doesn't get 
>> used), or completely changing the way 90% of the market runs PHP, which 
>> means frameworks will likely adapt to use that model primarily or 
>> exclusively (ie, less of a need for a "compile" step as a generated 
>> container or dispatcher is just held in memory automatically already).  The 
>> latter sounds exciting to me, but I'm not sure which is your intent, so I 
>> don't know if I'm going too far with it. :-)
>
> My intent is that most SAPIs expose the same (or a very similar 
> interoperable) worker mode. So (I hope) that most PHP developers will 
> not have to deal with these primitives directly, but that it will allow 
> a new generation of super-fast PHP apps to be created. Most frameworks 
> already support that but require a lot of boilerplate code to support 
> the different existing engines. Standardizing will likely increase 
> adoption and will allow collaboration to make the low-level code that I 
> propose to move in libphp as fast, stable, and clean as possible.

Do you have an intent or expectation of a worker-style SAPI being shipped with 
PHP itself, or for that to remain the domain of third parties?

>> Please advise on what the implications would be for the non-SAPI-developing 
>> PHP devs out there.
>
> None, except that they will be able to use the new handle_request() 
> function to create a worker script if supported by the SAPI they use.

I mean more what implications would there be on how user-space code is written 
to be worker-SAPI-friendly.  (The SQL connection comment above, for example.)  
I have not worked with any of the worker-ish tools so far myself, so other than 
"you'll need an alternate index.php for that", I don't have a good sense of 
what else I'd want to do differently to play nice with Franken and Friends.

The idea of combining fiber-based code with supported worker-mode runners 
sounds like a ridiculously cool future for PHP, but I don't know how windy that 
path is. :-)

--Larry Garfield

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



Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Kévin Dunglas
On Sun, Dec 24, 2023 at 10:44 PM Jordan LeDoux 
wrote:

>
>
> On Sat, Dec 23, 2023 at 12:34 PM Kévin Dunglas  wrote:
>
>> Hello and Merry Christmas!
>>
>> One of the main features of FrankenPHP is its worker mode, which lets you
>> keep a PHP application in memory to handle multiple HTTP requests.
>>
>> Worker modes are becoming increasingly popular in the PHP world. Symfony
>> (Runtime Component), Laravel (Octane), and many projects based on these
>> frameworks (API Platform, Sulu...) now support a worker mode.
>>
>> In addition to FrankenPHP, projects such as RoadRunner and Swoole provide
>> engines supporting worker modes.
>>
>> According to benchmarks, worker modes can improve the performance of PHP
>> applications by up to 15 times.
>> In addition to FrankenPHP, which is basically a SAPI for Go's integrated
>> web server, a new generation of SAPIs is currently under development.
>> Several SAPIs written in Rust (including one by the RoadRunner team) are
>> currently under development.
>>
>> These SAPIs, along with existing SAPIs, could benefit from a shared
>> infrastructure to build worker modes.
>>
>>
>>
>> The FrankenPHP code is written and should be easy to move around in PHP
>> itself, to enable other SAPIs to use it.
>>
>> In addition to sharing code, maintenance, performance optimization, etc.,
>> the existence of a common infrastructure would standardize the way worker
>> scripts are created and provide a high-level PHP API for writing worker
>> scripts that work with all SAPIs that rely on this new feature.
>>
>> SAPIs will still have to handle fetching requests from the web server and
>> pausing the worker to wait for new requests (in FrankenPHP, we use
>> GoRoutines for this, in Rust or C, other primitives will have to be used),
>> but almost everything else could be shared.
>>
>> For reference, here's the FrankenPHP code I propose to integrate into
>> libphp: https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L245
>>
>> The public API is documented here:
>> https://frankenphp.dev/docs/worker/#custom-apps
>>
>> I'd like to hear what the community thinks about this. Would you be
>> interested in this functionality in PHP? Should I work on an RFC?
>>
>> If there's interest, I can work on a patch.
>>
>> Cheers,
>> --
>> Kévin Dunglas
>>
>
> Much like Larry, I'm curious what sort of scope you imagine for this. Are
> you imagining something that is geared specifically towards HTTP requests,
> or would this be a more generic "PHP Application Worker" that might be
> spawned to handle other types of applications? Could we have a worker
> listen to a specific port and respond to or handle all requests on that
> port/device?
>
> Jordan
>

Ho Jordan,

Yes, the scope I imagine is geared specifically towards HTTP requests.
Something more generic than common primitives for SAPIs and a shared public
API to handle HTTP requests with a long-running PHP worker script will be
hard to do outside of SAPIs because they depend on a lot of external
concerns such as the programming language the SAPI is using.


Re: [PHP-DEV] RFC proposal: worker mode primitives for SAPIs

2023-12-25 Thread Kévin Dunglas
On Sun, Dec 24, 2023 at 4:21 PM Larry Garfield 
wrote:

In practice, I want to understand the implications for user-space code.
> Does this mean FPM could be configured in a way to execute a file like that
> shown in the docs page above?  Or would it only work with third party SAPIs
> like FrankenPHP?


In theory, PHP-FPM and the Apache module could - like all other SAPIs - be
enhanced to add a worker mode operating as described in the FrankenPHP doc
thanks to these new primitives.

However, I suggest doing this as a second step, because as described in my
first post, it will still be the responsibility of each SAPI to manage
long-running processes and communication with them. This is simple to do
with Go's GoRoutine and Rust's asynchronous runtimes such as Tokio, it's
definitely more difficult in cross-platform C. I suggest starting by adding
the primitives to libphp, then we'll see how to exploit them (and whether
it's worthwhile) in the built-in SAPIs.
I personally have less interest in working on FPM/CGI/mod_php as the other
possibilities offered by modern SAPIs like FrankenPHP are more important
(better deployment experience as you have a single static binary or Docker
image, Early Hints support, high-quality native HTTP/3 server etc), but I'd
be happy to help if anyone wants to update these SAPIs.

I assume the handler function would be differently named.


I suggest naming the function handle_request() or something similar and
using the same name for all SAPIs, so the same worker script will work
everywhere. I'll update FrankenPHP to use the "standard" name.


> Is passing in super-globals the right/best way to handle each request, or
> would it be sensible to have some other abstraction there?  (Whether a
> formal request object a la PSR-7 or something else.)


Passing super-globals is at the same time the most interoperable solution
(it allows using almost all existing PHP libraries in worker mode without
any change to them), and also allows to reuse of the existing C code.
Transforming super-globals in HttpFoundation, PSR-7, or other objects is
straightforward and can entirely be done userland (it's already what the
Symfony Runtime Component and Laravel Octane do), so there is no need to
"bloat" the C code.

Having more high-level data structures to manipulate HTTP messages similar
to HttpFoundation or PSR-7 in the language could be nice (and is in my
opinion needed), but is a separate topic.
If PHP adds a new abstraction for that at some point, it will be easy to
add support for them both in standard and worker mode.


> To what extent would user-space code run this way have to think about
> concurrency, shared memory, persistent SQL connections, etc?  Does it have
> any implications for fiber-using async code?
>

Regarding concurrency, it doesn't change much (it's similar to existing
SAPI). Regarding memory and SQL connections, extra care is required. Memory
leaks (and other kinds of leaks) should be avoided (or workers should
restart from time to time, which is obviously a poorer solution). Libraries
maintaining SQL connections such as Doctrine or Eloquent must ensure that
the connection isn't active.
The good news is that thanks to RoadRunner, Swoole, Laravel Octane, Symfony
Runtime etc... Most popular libraries are already compatible with
long-running processes, and most issues have been fixed.
Some old apps and libraries will probably never be updatable, but that's
not a big issue because this feature will be entirely opt-in.

Fibers work as expected. There is a small limitation when using them with
Go (that is being tracked in the Go runtime,
https://frankenphp.dev/docs/known-issues/#fibers), but it's not related to
the C code of the worker mode, and this limitation shouldn't exist for
SAPIs not written in Go.


> Depending on the details, this could be like fibers but for 3rd party
> SAPIs (something about 4 people in the world actually care about directly,
> everyone else just uses Revolt, Amp, or React, but mostly it doesn't get
> used), or completely changing the way 90% of the market runs PHP, which
> means frameworks will likely adapt to use that model primarily or
> exclusively (ie, less of a need for a "compile" step as a generated
> container or dispatcher is just held in memory automatically already).  The
> latter sounds exciting to me, but I'm not sure which is your intent, so I
> don't know if I'm going too far with it. :-)
>

My intent is that most SAPIs expose the same (or a very similar
interoperable) worker mode. So (I hope) that most PHP developers will not
have to deal with these primitives directly, but that it will allow a new
generation of super-fast PHP apps to be created. Most frameworks already
support that but require a lot of boilerplate code to support the different
existing engines. Standardizing will likely increase adoption and will
allow collaboration to make the low-level code that I propose to move in
libphp as fast, stable, and clean as possible.


>