clue/reactphp-block

Await goes into infinite loop

sorenbronsted opened this issue · 3 comments

I am trying to use reactphp in my application without rewriting the whole thing to promises but to use await instead. I have though some problems with await which I can boil down to this example:

<?php

use Psr\Http\Message\ServerRequestInterface;
use React\EventLoop\Loop;
use React\Http\Browser;
use React\Http\HttpServer;
use React\Http\Message\Response;
use React\Socket\SocketServer;
use function Clue\React\Block\await;

require 'vendor/autoload.php';

$http = new HttpServer(function (ServerRequestInterface $request) {
    echo $request->getMethod() . ' ' . $request->getUri() . PHP_EOL;
    return new Response(
        200,
        array(
            'Content-Type' => 'text/plain'
        ),
        "Hello World!\n"
    );
});

$socket = new SocketServer('127.0.0.1:8080');
$http->listen($socket);

$txn = 1;
$preventInfiniteLoop = false;

$loop = Loop::get();
$loop->addPeriodicTimer(1, function() use(&$txn, &$preventInfiniteLoop) {
    $browser  = new Browser();
    echo "$txn Timer running" . PHP_EOL;

    // Synkron version
    if ($preventInfiniteLoop) {
        return;
    }
    $preventInfiniteLoop = true;
    $response = await($browser->get('http://localhost:8080'));
    echo $response->getBody() . PHP_EOL;


    // Asyncron version
    // $browser->get('http://localhost:8080')->then(function(ResponseInterface $response) {
    //     echo $response->getBody() . PHP_EOL;
    // }, function(Exception $error) {
    //     var_dump($error);
    // });


    $preventInfiniteLoop = false;
    $txn++;
});

echo "Server running at http://127.0.0.1:8080" . PHP_EOL;

Then asyncron works out of the box, but the syncron way has 2 issue:

  1. it goes into infinite loop
  2. i can prevent the infinite loop, but then it stops the server.

@sorenbronsted Thanks for bringing this up! @clue made a good job at answering this problem inside #62.

The await function also starts a new loop which in your case leads to two loops running at once and only one is going to be stopped.

I believe this has already been answered in other tickets, so I'm closing this for now. Please come back with more details if this problem persists and we can always reopen this 👍

May I suggest that the limitations of this library are clearly state in the readme possibly by linking to issue many has raised. It will save time for all of us :-)

clue commented

@sorenbronsted Fair enough, we're currently in process of moving towards a stable release for react/async and have also moved the await() function as per reactphp/async#8. Together with reactphp/async#15 and reactphp/async#26, we're also starting to migrate to fibers introduced in PHP 8.1 which doesn't have any of these limitations. This project continues to work as-is, but once this migration is completed, we'll likely soft-deprecate this project to help migrate users to the newer replacement.

If you feel there's anything that should be added to this README, I'm happy to accept PRs! 👍