phpinnacle / ridge

Pure asynchronous PHP implementation of the AMQP 0-9-1 protocol.
MIT License
50 stars 13 forks source link

Heartbeat not working on RabbitMQ server restarted #34

Closed PNixx closed 2 years ago

PNixx commented 2 years ago

Version 1.3.0 with fixed PR https://github.com/phpinnacle/ridge/pull/33

Example code:

\Amp\Loop::run(function() {
    $client = Client::create("amqp://guest:guest@localhost:5672/?timeout=5000&heartbeat=2000");
    yield $client->connect();
    print_r('Connected: ' . $client->isConnected() . PHP_EOL);
    \Amp\Loop::repeat(1000, fn() => print_r('Connected: ' . $client->isConnected() . PHP_EOL));
});

I add debug lines before write, before check condition and add log in close method https://github.com/phpinnacle/ridge/blob/0f8621758daec95aab0ba3d34534e47fd9bb1b74/src/Connection.php#L179-L195

print_r('write' . PHP_EOL);
yield $this->write((new Buffer)
...
print_r('check' . PHP_EOL);
if (

Run script and see in log:

Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1

Checking heartbeat correctly. But I simulate RabbitMQ server down with command brew services restart rabbitmq I see in log:

Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
close
Connected: 1
Connected: 1
Connected: 1
Connected: 1
Connected: 1
mmasiukevich commented 2 years ago

Heartbeat, formally, should not work when the Rabbit is rebooted.

I added an observer, it will notice such moments so that the client simply doesnt freeze without signs of life.

In theory, we can implement something like automatic recovery. But there are nuances here, it is not yet very clear what to do with open channels.

PNixx commented 2 years ago

I fixed it in pull request #33