Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if the connection is open #712

Open
PandarinDev opened this issue Oct 19, 2021 · 1 comment
Open

Check if the connection is open #712

PandarinDev opened this issue Oct 19, 2021 · 1 comment

Comments

@PandarinDev
Copy link

PandarinDev commented Oct 19, 2021

There is a heartbeat mechanism in place - what I found out from reading the code is that on AMQP_STATUS_HEARTBEAT_TIMEOUT the socket close method is called, which in return closes the socket and sets it's file descriptor to "-1".

So my question is, is there any more robust way of checking if the connection is alive than checking if the socket's FD is -1?

See my answer below on how I ended up detecting connection issues.

@PandarinDev
Copy link
Author

PandarinDev commented Oct 25, 2021

I spent almost a full workday figuring this out, so I'll share what I found: Heartbeat is not exactly useful, things only timeout if you actually wait longer than the heartbeat period, eg. if your message timeout is 5 seconds (in a loop so that you can stop listening if you need to) and the heartbeat timeout is 30 seconds, then heartbeat will do nothing for you.

You actually need to rely on the error codes returned by the different function calls to figure out if the connection was broken, which is tricky because the error codes are different when you're using an SSL connection vs. a non-SSL connection. Namely, you'll receive AMQP_RESPONSE_LIBRARY_EXCEPTION with library_error set to either AMQP_STATUS_CONNECTION_CLOSED, AMQP_STATUS_SOCKET_ERROR (in case of a non-SSL connection) or AMQP_STATUS_SSL_ERROR (in case of an SSL connection).

Furthermore, if the server is initiating shutdown you'll receive a different error code again (AMQP_STATUS_UNEXPECTED_STATE) in which case you actually have to check the next frame (using amqp_simple_wait_frame) and use that to figure out if it was a server shutdown message. You can do that by checking if the frame is a AMQP_FRAME_METHOD and the method ID is AMQP_CONNECTION_CLOSE_METHOD.

In all of these cases if you try to close the channel or connection (which might be unnecessary, I'm not sure it is in all cases) you might receive these errors again, so make sure you have special error handling there too. Also make sure you call amqp_destroy_connection before you reconnect every time, otherwise you will leak memory.

Maybe this could be made a little more transparent in the documentation? It was a huge hassle figuring this out for automatic reconnect in case of connection loss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant