bunny icon indicating copy to clipboard operation
bunny copied to clipboard

Hangs on fail-connect

Open IAkumaI opened this issue 8 years ago • 4 comments

When async client try to connect to RabbitMQ which down (or not exists) its just hangs. No errors, no exceptions...no reaction.

Reactphp loop stil works, but Bunny hangs.

Is it my problem only or mass bug?

As a temp solve I add timer to loop:

$loop->addTimer(10, function () {
    if (!$this->isReady()) {
        throw new Exception('Client is not ready yet');
    }
});

IAkumaI avatar Nov 03 '17 22:11 IAkumaI

I can confirm this. Not even having timeouts in the connection helps.

ondrejmirtes avatar Nov 03 '17 22:11 ondrejmirtes

Thank you for reporting the issue. Currently, I don't have time to investigate further, or fix it. Would be really glad for PR.

jakubkulhan avatar Nov 06 '17 20:11 jakubkulhan

I can also confirm this issue. It is very likely caused by a blocking call here: https://github.com/jakubkulhan/bunny/blob/d0dec8fbbac4e4edd6cdc892fe14cfa607c386ce/src/Bunny/Async/Client.php#L195 which then ends up here: https://github.com/jakubkulhan/bunny/blob/d0dec8fbbac4e4edd6cdc892fe14cfa607c386ce/src/Bunny/AbstractClient.php#L232

As an alternative, this class would have to be updated to use ReactPHP's react/socket to asynchronously create a connection. This should take care of using a non-blocking DNS query and also automatically applying a connection timeout.

I've started looking into implementing this here, but unfortunately the getSocket() class is used in a number of places, so this would require a non-trivial update.

clue avatar Mar 16 '18 11:03 clue

One solution here appears to be to use the $onRejected parameter of ->then():

    $bunny->connect()->then(function (Client $client) {
            print "Connecting\n";
            return $client->channel();
        }, function($reason) {
            // The documentation doesn't appear to put any limits on what $reason might be,
            // so I'll start by assuming it's probably a string or throwable.
            $reasonMsg = "";
            if (is_string($reason)) {
                $reasonMsg = $reason;
            } else if ($reason instanceof Throwable) {
                $reasonMsg = $reason->getMessage();
            }
            print "Rejected: ". $reasonMsg ."\n";
        })

AllenJB avatar Jul 05 '18 13:07 AllenJB