How to properly use async awaitAll in PHPReact?

81 Views Asked by At

I make a educational lesson with Async library https://reactphp.org/async/. Want to figure out how to work in async mode properly.

So I made a 3 scripts. All 3 scripts connect to database 12 times.

First script finish work in 26 seconds https://github.com/Carsak/php-react/blob/main/create-connections.php

Second script finish work in 26 seconds too https://github.com/Carsak/php-react/blob/main/create-connections-async.php

I read documentation and found this

The previous example uses await() inside a loop to highlight how this vastly simplifies consuming asynchronous operations. At the same time, this naive example does not leverage concurrent execution, as it will essentially "await" between each operation. In order to take advantage of concurrent execution within the given $function, you can "await" multiple promises by using a single await() together with Promise-based primitives like this:

So I rewrote script and made 3 variant https://github.com/Carsak/php-react/blob/main/create-connections-async-correct.php This script finish in 2 second and does not invoke connecting to DB. No iteration has been invoked

Could anybody suggest why this script did not work?

1

There are 1 best solutions below

0
On

FYI: I already gave an answer for this question on GitHub, for better visibility I'll also post my answer here:

First important thing to note is that the async() function only works in tandem with the await() function and does not "magically" make any blocking function non-blocking:

Loop::addTimer(0.5, React\Async\async(function () {
    echo 'a';
    sleep(1); // broken: using PHP's blocking sleep() for demonstration purposes
    echo 'c';
}));

Loop::addTimer(1.0, function () {
    echo 'b';
});

// prints "a" at t=0.5s
// prints "c" at t=1.5s: Correct timing, but wrong order
// prints "b" at t=1.5s: Triggered too late because it was blocked

This means, file_get_contents() or using PDO will still be blocking in your examples. You can avoid this by using functions and components that are designed for non-blocking I/O. For example, instead of using a blocking PDO you could use https://github.com/friends-of-reactphp/mysql.

You can read all about async and await in our reactphp/async documentation. I also gave a quick explanation on async() and await() in https://github.com/orgs/reactphp/discussions/546#discussioncomment-7640814, maybe this also helps.