Introduce PHP Fiber to Laravel; e.g., to support parallel DB querying #47077
Replies: 3 comments
-
As far as I can tell (i.e. guess), and as stated above, you would indeed need to programme your application to do things in parallel i.e. have some Laravel interfaces to start things running in parallel and then to wait until one or more of them have completed and the data is available. IMO ideally you would want this to be a lot more flexible than the pseudocode above which is a way of parallelising just DB calls and then wait for them all to complete. So e.g.
In other words you might want to do something more akin to:
In essence you need to have some generic way of splitting into parallel streams and then combining them back again, and you would need the whole of the Laravel code to be Fibre safe/aware against random sequencing of access to shared objects (in the same way that other languages that use native threading need to be thread safe/aware). PHP closures would appear (at first glance) to help with this, because "A closure encapsulates its scope, meaning that it has no access to the scope in which it is defined or executed.". It appears to me that the four challenges are:
I suspect that these are NON-TRIVIAL. |
Beta Was this translation helpful? Give feedback.
-
Could you give a bit more context to this one - are there options available in Guzzle which provide fully non-blocking parallel requests? Laravel has some parallel functionality in the Http client too, but AFAK these are blocking and runs in separate threads. It would truly be a game changer if parallel Http requests could be implemented in a non-blocking way. I've come across https://amphp.org, but I've yet to try out if it can be combined with Laravel Http client. |
Beta Was this translation helpful? Give feedback.
-
Upon self-reflection, I realized I have remembered the entire thing wrongly. Even if we use php-curl, we still encounter this section of code: // pseudocode
$multi = curl_multi_init();
// add your requests here...
curl_multi_add_handle($multi, null);
// let's say all the requests are already added to the multi-curl instance...
// note that no HTTP requests have been sent yet!
$active = null;
do {
// this blocks until there is an update
// this update can be e.g. "requests sent", "response received", "timeout"
$status = curl_multi_exec($multi, $active);
// you can now do something else, e.g. sleep(10);
// you can always call curl_multi_exec() again to see how things are going, and receive the responses etc.
} while ($active); So yeah, the entire PHP HTTP situation is unfortunately blocking. Apologies for mistaking things. Therefore, the idea by @rasmuscnielsen about implementing a truly non-blocking HTTP client is suddenly very attractive to me. I've also come across AMPHP myself earlier, but I have largely forgot about it until the mention; and I also have not tried it yet. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
A continuation of the issue from the archived repo: laravel/ideas#2540
It seems there are some opportunities to achieve parallel processing in Laravel by using PHP 8.1 Fibers, e.g. by introducing parallel DB querying.
First responding to the original post, it mentioned 4 contexts:
Some of the above contexts actually do not need PHP Fibers to be processed in parallel:
Guzzle HTTP or even the PHPupdate: I remembered something wrongly, see Introduce PHP Fiber to Laravel; e.g., to support parallel DB querying #47077 (comment)curl
extension can already process parallel requests by themselvesThis leaves Context 2 unresponded.
This is where I think Fibers may be useful to Laravel: database connections. Specifically, the potential ability to run multiple DB queries in parallel without one blocking the other.
One existing use case could be this: sometimes, when I try to insert many data into MySQL via Laravel Eloquent, I find that the data size exceeded the MySQL binding limit of 65536. To insert them, I will have to chunk them into several queries. However, if I know that the exact order of insertion does not matter, then I can use Fibers to issue several parallel queries to the DB, and just wait all of them to complete.
So, instead of this:
Perhaps I can do the following:
One potential new use case is this: e.g., for whatever reason, I know that I will have to load quite some data from multiple DB tables, and I already know for each table which IDs are needed. Those tables are not related to each other through foreign keys, etc. Currently I have to do something like this:
Then, with Fibers, since both tables are unrelated, perhaps I can do something like this:
Of course, parallel DB querying can be done already without using Fibers (can be discussed in another topic). But for something this fundamental, it is surprising that there is no equivalent operation in Laravel or any of its dependent libraries. What we currently have close to parallel querying is when loading relations in one line of code, but if those data are not related by relationships, then we currently have nothing.
Therefore, it seems Laravel can try to use Fiber to allow for DB querying in parallel.
Beta Was this translation helpful? Give feedback.
All reactions