redis-py icon indicating copy to clipboard operation
redis-py copied to clipboard

`Redis()` doesn't raise exception even when no redis server is running and it cannot connect, for both sync and async instantiation.

Open lb1mg opened this issue 2 years ago • 1 comments

Version: redis-py 4.6.0

Platform: Python 3.11.4 on Mac A1

Description: The ConnectionError is raised on the first command executed to communicate with the server (e.g. .ping()).

  1. Is this intended behaviour to not raise exception even when Redis() can not connect to redis server?
  2. Where can I find detailed connection process?
  3. Is there any way to set verbosity and print connection progress/steps?
  4. And how & when do "retry helpers" (https://redis.readthedocs.io/en/stable/retry.html) come into play if Redis() itself doesn't raise an exception on failed connection?

Thank You.

lb1mg avatar Jul 30 '23 14:07 lb1mg

import logging
import redis
from redis.exceptions import ConnectionError, TimeoutError

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('redis')

def create_redis_client(host='localhost', port=6379, db=0, max_retries=5):
    # Create Redis client
    client = redis.Redis(host=host, port=port, db=db)

    # Attempt to connect and retry if necessary
    retries = 0
    while retries < max_retries:
        try:
            # Test the connection
            client.ping()
            logger.info("Connected to Redis server.")
            return client
        except (ConnectionError, TimeoutError) as e:
            retries += 1
            logger.warning(f"Attempt {retries} failed: {e}")
            if retries == max_retries:
                logger.error("Max retries reached. Could not connect to Redis server.")
                raise
            else:
                logger.info(f"Retrying... ({retries}/{max_retries})")

# Example usage
try:
    redis_client = create_redis_client()
    # Perform Redis operations
    redis_client.set('foo', 'bar')
    value = redis_client.get('foo')
    print(f"Value for 'foo': {value.decode('utf-8')}")
except ConnectionError as e:
    logger.error(f"Could not connect to Redis server: {e}")
except Exception as e:
    logger.error(f"Unexpected error: {e}")

ljluestc avatar Jun 23 '24 22:06 ljluestc

Hi, when the client is created, its properties are initialized, but no connection to the server is tested at that stage. The retry configuration is applied only when commands are sent to the server.

If validating connectivity at that moment is crucial, the provided example above can be used as a workaround.

You can find additional usage examples in the documentation: Redis Library Examples.

Closing this issue for now. Please feel free to reopen it if further assistance is needed.

petyaslavova avatar Feb 05 '25 16:02 petyaslavova