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

How to check is a connection ok? #877

Closed
zhangzx7054 opened this issue Sep 24, 2017 · 3 comments
Closed

How to check is a connection ok? #877

zhangzx7054 opened this issue Sep 24, 2017 · 3 comments

Comments

@zhangzx7054
Copy link

zhangzx7054 commented Sep 24, 2017

I tried to use channel.is_open and connetcion.is_open to get the connection's and channel's status, but failed.
The return value is always True, even though I stopped rabbitmq server.
Here is my test code.

import pika 
import time

 credit = pika.PlainCredentials(username='cloud', password='cloud')
 connection = pika.BlockingConnection(pika.ConnectionParameters(host='10.32.1.12', credentials=credit))
 channel = connection.channel()

while True:
     connect_close = connection.is_closed
     connect_open = connection.is_open
     channel_close = channel.is_closed
     channel_open = channel.is_open
     print("connection is_closed ", connect_close)
     print("connection is_open ", connect_open)
     print("channel is_closed ", channel_close)
     print("channel is_open ", channel_open)
     print("")
     time.sleep(5)

Here is the print log. When rabbitmq server stops, the print log is still the same as below.
bvvzmq

@lukebakken
Copy link
Member

lukebakken commented Oct 10, 2017

Hello @zhangzx7054 -

Since you are using a BlockingConnection, heartbeats will only be processed if you actually do something with the channel. You can see this behavior with the following code:

import logging
import pika 
import time

logging.basicConfig(level=logging.DEBUG)

creds = pika.PlainCredentials(username='guest', password='guest')
params = pika.ConnectionParameters(host='localhost', credentials=creds,
                                   heartbeat_interval=10, blocked_connection_timeout=10)
connection = pika.BlockingConnection(params)
channel = connection.channel()

while True:
     print(time.strftime('%c', time.localtime()))
     channel.basic_publish('', 'my-alphabet-queue', 'abc')
     connect_close = connection.is_closed
     connect_open = connection.is_open
     channel_close = channel.is_closed
     channel_open = channel.is_open
     print("connection is_closed ", connect_close)
     print("connection is_open ", connect_open)
     print("channel is_closed ", channel_close)
     print("channel is_open ", channel_open)
     print("")
     time.sleep(5)

If you use one of the asynchronous adapters for your client code, you will also see the heartbeat mechanism detect lost connections. Please refer to the example code.

@austinnichols101
Copy link

austinnichols101 commented Nov 29, 2017

@lukebakken Is there a way to directly trigger a heartbeat send_and_check with a BlockingConnection?

My current workaround to "do something with the channel" is to check for the existence of an exchange, but I would prefer to simply force a heartbeat to show RMQ that my process is still alive.

self._channel.exchange_declare(exchange=self.EXCHANGE, passive=True)

More specifically, I would like to be able to manually send a heartbeat frame from a BlockingConnection.

self._connection._send_frame(self._new_heartbeat_frame())

@vitaly-krugl
Copy link
Member

If you periodically call BlockingConnection.process_data_events or BlockingConnection.sleep() it will attempt to send a heartbeat when it's time, and should raise ConnectionClosed when it fails to send on a closed TCP/IP stream.

In practice, you have to be prepared any time for a dropped connection (RabbitMQ issue, network issue, etc.). Checking a connection just before sending something is not guarantee that connection won't be lost while your're sending, so you need to anticipate re-connection and retries. For example, see _RETRY_ON_AMQP_ERROR decorator and _ChannelManager wrapper of AMQP client

paramsingh added a commit to paramsingh/listenbrainz-server that referenced this issue Nov 21, 2018
We cannot directly use the `is_open` property that pika's
BlockingConnection provides because the heartbeat mechanism
does not detect closed connections itself.

See: pika/pika#877

This lead to a lot of ConnectionClosed errors in the API which
was the main cause of almost all the Sentry errors.
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

4 participants