Is ReactPHP truly asynchronous?
Asked Answered
O

1

38

I've been doing some tests on ReactPHP because it looks pretty awesome. I've tested it with the following react/socket code, for a simple socket server.

$loop = React\EventLoop\Factory::create();

$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn) {
    echo 'New client !';

    $conn->on('data', function ($data) use ($conn) {
        $conn->write("Wow, some data, such cool\n");
        $conn->close();
    });
});
$socket->listen(1337);

$loop->run();

Until this point there's no problem. The server shows New client ! when a client is connected and the client receives the response.

But I done a new test, with more processing on the data event. To illustrate my words, I'll add a for loop that will take a few milliseconds to complete :

$conn->on('data', function ($data) use ($conn) {
    $conn->write("Wow, some data, such cool\n");

    for ($i=0; $i<10000000; $i++); // here

    $conn->close();
});

In this case, with 10 clients, the client will show the text Wow, some data, such cool after all clients processing (so ~2 seconds), but server will show New client ! without waiting.

So here my lack of understanding, ReactPHP is an asynchronous I/O, but PHP is single-threaded, and if there is a lot of processing between input and output, that will block all clients.

Overpower answered 19/3, 2014 at 9:58 Comment(5)
https://mcmap.net/q/73965/-how-can-one-use-multi-threading-in-php-applicationsPseudonym
I'm not asking if PHP can do multi-threading, i'm using github.com/krakjoe/pthreads in another project, but, in a nutshell, if I've reached the limit of this lib.Overpower
The library is basically a wrapper around stream_socket_server as far as I can see. The question is whether stream_socket_server is asynchronous. Given PHP's basic architecture that would surprise me, but I do not know the definite answer.Twum
You can setting non blocking socket server with stream_set_blocking(stream, true or false)Overpower
Sure, but: "This affects calls like fgets() and fread() that read from the stream. In non-blocking mode an fgets() call will always return right away while in blocking mode it will wait for data to become available on the stream." - This says nothing about asynchronous handling...Twum
H
56

ReactPHP is an asynchronous I/O, but PHP is single-threaded, and if there is a lot of processing between input and output, that will block all clients.

Yes.

ReactPHP is very much inspired by node.js, which follows the same principle. The goal of such event-based patterns is not to exploit your server 16 CPU's, but to exploit fully your processor by processing HTTP request B while your controller for request A, which has made request to database, is paused until the 'database request success' event is called.

Your test is going exactly against the assumption made by node.js and ReactPHP: "computation is fast, I/O are slow", so if we do computation during I/O (and not between I/O), then CPU time will always be available in higher quantity than needed.

With node.js or ReactPHP if you want to use your server 16 CPU, you just launch 16 server process on 16 port and put a load balancer like nginx in front of them.

But keep in mind ReactPHP is still experimental and not ready for production.

Howler answered 5/6, 2014 at 18:39 Comment(2)
What about Kraken or Swoole? Are those also experimental? And how are they different from amphp?Ironbark
you should watch this video and decide yourself. v=fQxxm4vD8OkRadiosurgery

© 2022 - 2024 — McMap. All rights reserved.