WyriHaximus / react-guzzle-http-client

Meta package for ReactPHP HttpClient adapters/handles for Guzzle 4, 5, and 6.
MIT License
10 stars 8 forks source link

Loop hangs if timeout happens #12

Open DangerLifter opened 6 years ago

DangerLifter commented 6 years ago

Seems I faced another issue with Timeout. Probably it is an issue with react socket library, or mb it correlates with https://github.com/WyriHaximus/react-guzzle-http-client/issues/11

Url that helps reproduce issue is 'http://pomeranians.eplus2.jp/article/41931382.html' Sometimes it works - but most of time it does not

Running scripts expect Timeout as TcpConnector can't connect. And without ring it works.

php ./testTimeout.php Request at: 09:10:42 BEFORE LOOP AFTER LOOP Error at: 09:10:43 cURL error 28: Timeout was reached

But using ring causes loop hanging. I debug loop calls and you can find that "write stream 141" is added into loop but not removed on timeout. Stream is added by: /var/www/projects/DomainScrapperUpd/vendor/react/socket/src/DnsConnector.php:81

$ php ./testTimeout.php --use-ring Request at: 09:10:49 BEFORE LOOP /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:48: string(19) "add read stream 131" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:62: string(20) "add write stream 131" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:125: string(11) "add timer 5" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:125: string(11) "add timer 3" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:125: string(11) "add timer 2" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:91: string(23) "remove write stream 131" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:77: string(22) "remove read stream 131" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:105: string(17) "remove stream 131" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:149: string(14) "cancel timer 5" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:62: string(20) "add write stream 141" Error at: 09:10:51 Timed out after 2 seconds /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:149: string(14) "cancel timer 2" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:149: string(14) "cancel timer 2" /var/www/projects/DomainScrapperUpd/vendor/react/event-loop/src/ExtEventLoop.php:149: string(14) "cancel timer 3" .... HANGING .....

require __DIR__ . '/bootstrap/autoload.php';

$loop = \React\EventLoop\Factory::create();
$options = [
    'defaults' => [
        'timeout' => 1, //sec,
        'connect_timeout' => 2, //sec,
    ]
];

if (in_array('--use-ring', $argv)) {
    $innerOptions = [
        'timeout' => 3,
    ];
    $handler = new \WyriHaximus\React\RingPHP\HttpClientAdapter(
        $loop,
        new \React\HttpClient\Client(
            $loop, new \React\Socket\Connector($loop, $innerOptions)
        )
    );
    $options['handler'] = $handler;
}

$httpClient = new \GuzzleHttp\Client($options);

$url = 'http://pomeranians.eplus2.jp/article/41931382.html';
echo "Request at: ".date('H:i:s')."\n";
$httpClient
    ->get($url, ['future' => true])
    ->then(
        function ($v) {echo "Done at: ".date('H:i:s')."\n";},
        function ($v) {echo "Error at: ".date('H:i:s')." ".$v->getMessage()."\n";}
    )->done();

echo "BEFORE LOOP \n";
$loop->run();
echo "AFTER LOOP \n";