Hi and thanks for the latest great features.
Idea visualized:
https://drive.google.com/file/d/1twuCTk2ssNl5damTydP-aOmOeJ5hWr9r/view?usp=sharing
This is an idea and it's simple on the paper: *To run the requests coming
to PHP Frameworks in three phases. *
Let's say FPM pool child processes can run PHP instances in two-phase:
Initialization Phase: It runs an instance of our PHP code with no
request information given. The running PHP code is interrupted by some kind
of input mechanism which is put deliberately by the developer into the
code. FPM will keep this process on RAM waiting for a request to come in.
-
Waiting Phase
Running Phase: There are a bunch of code instances in the waiting phase,
one of them should be given the request to handle and respond back.
Now this will give us the ability to write codes or frameworks that run
faster. Let’s say that Laravel (any PHP project or framework) works like
this:
It loads all its dependencies, providers, routes, configs and creates a
connection to the database and the cache systems and any other have-to-run
things which are necessary to handle a request
Then it waits for the request by simply putting something like a
“fgets(STDIN)” ( any mechanism proposed by FPM )
When input/request is given in some format, it continues running,
handles the request, and responds back
With this approach, we can remove the part of the time that PHP spends on
Initializing frameworks for every single request and improve response times.
I think that having Opcache + Preloading Files + This Proposal can
significantly improve frameworks response times.
The benefit of this approach over Ratchet, Fiber, or other RealTime works,
is that it doesn't depend on PHP's memory handling problems so that can be
used in production with more confidence.
Please let me hear your feedback, thanks.
Best wishes,
Mohammad Eftekhari
Hey,
I have seen this a while ago and it looks promising, however, I do have my
fair share of concerns, namely:
- We should be able to define some sort of TTL. What happens if no request
comes for over an hour? Albeit this is really unlikely. - Why not implement a mechanism similar to
fork
for these new requests?
So that we duplicate the memory of the process and are able to spawn new
instances way faster. - How many instances will be kept in (I suppose) a pool for answering the
requests?
Regarding database connections, almost all adapters support some form of
connection pooling, so the example you mention about a database connection
is a bit obsolete in my opinion. Furthermore, how will we deal with
database timeouts, resource exhaustion, and many other problems that might
arise when stalling certain processes for too long?
Just to see what we should do about the aforementioned issues, I propose
that you create some sort of a basic implementation at first, so that
benchmarks can at least show us how much of a difference this makes. As far
as I can see, the difference will be negligible since most modern
frameworks do allow you to generate PHP files, which get pre-compiled by
OPCache, and thus already give amazing performance.
Also, extensions like APCu go unnoticed and already greatly help storing
e.g. pre-compiled routes, if you do not want to generate PHP files.
For now, this will require some more discussion.
Kind regards,
Harm Smits
Have you tried Roadrunner? I think your design is quite similar (identical?) to what Roadrunner does, only that your
worker pool is managed by FPM instead of Roadrunner and that the worker exits after serving one request - which you
can do with Roadrunner, but it's not recommended.
Have you tried Roadrunner? I think your design is quite similar (identical?) to what Roadrunner does, only that your
worker pool is managed by FPM instead of Roadrunner and that the worker exits after serving one request - which you
can do with Roadrunner, but it's not recommended.
Also, since OP mentioned Laravel, https://github.com/laravel/octane/ has
been made public recently.
It was announced on the recent Laracon. There's no official release yet
though development seems in super-full-force mode and it supports Swoole
and RoadRunner.
I think they're aiming for the "killer app" (well, framework) here.
- Markus
Hi,
On Fri, Apr 9, 2021 at 5:48 PM Mohammad Eftekhari bluemmb22@gmail.com
wrote:
Hi and thanks for the latest great features.
Idea visualized:
https://drive.google.com/file/d/1twuCTk2ssNl5damTydP-aOmOeJ5hWr9r/view?usp=sharing
This is an idea and it's simple on the paper: *To run the requests coming
to PHP Frameworks in three phases. *Let's say FPM pool child processes can run PHP instances in two-phase:
Initialization Phase: It runs an instance of our PHP code with no
request information given. The running PHP code is interrupted by some
kind
of input mechanism which is put deliberately by the developer into the
code. FPM will keep this process on RAM waiting for a request to come
in.
This is basically what was drafted in
https://github.com/php/php-src/pull/6772 . I would recommend you to read
that PR discussion for details. To sum it up, the tricky part is the
implementation as it has to work with all PM's and reload. Most likely we
will need to introduce event (epoll on Linux) based loop in the child
accepting to be able to properly clean it up. In addition a new request
stage will be likely needed and then sorting all the possible edge cases
out.
Regards
Jakub