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

Redis pubsub task cancellation raises ConnectionError #2717

Open
cosminacho opened this issue Apr 21, 2023 · 4 comments
Open

Redis pubsub task cancellation raises ConnectionError #2717

cosminacho opened this issue Apr 21, 2023 · 4 comments

Comments

@cosminacho
Copy link

Version: 4.5.4

Platform: Windows / Linux - Python 3.10.10

Description: When cancelling a pubsub task that is listening for messages, the ConnectionError exception is thrown. This seems like an internal library problem because I can't catch the exception inside redis_subscribe function and the exception is thrown only after the CancellationError is raised inside the task.

Is this the intended behaviour? If so, what is an elegant work-around?

This code used to work in the previous versions of redis (4.5.3 an below).

redis_client is a global variable, initialized on the startup event of a server. The redis_subscribe function is supposed to be called inside endpoints that feed messages using websockets or server sent events. So the cancellation of the task needs to happen when for example a client disconnects from the server.

from redis.asyncio import Redis

import asyncio

redis_client = Redis()

async def redis_subscribe():
    async with redis_client.pubsub() as pubsub:
        pubsub.subscribe("channel")
        async for message in pubsub.listen():
            print(message)

task = asyncio.create_task(redis_subscribe())

asyncio.sleep(5)

task.cancel()

asyncio.sleep(5)
Task exception was never retrieved
future: <Task finished name='Task-27' coro=<Retry.call_with_retry() done, defined at redis/asyncio/retry.py:46> exception=ConnectionError('Connection closed by server.')>
Traceback (most recent call last):
  File "redis/asyncio/retry.py", line 62, in call_with_retry
    await fail(error)
  File "redis/asyncio/client.py", line 779, in _disconnect_raise_connect
    raise error
  File "redis/asyncio/retry.py", line 59, in call_with_retry
    return await do()
  File "redis/asyncio/client.py", line 784, in _try_execute
    return await command(*arg, **kwargs)
  File "redis/asyncio/connection.py", line 840, in read_response
    response = await self._parser.read_response(
  File "redis/asyncio/connection.py", line 413, in read_response
    await self.read_from_socket()
  File "redis/asyncio/connection.py", line 396, in read_from_socket
    raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR) from None
redis.exceptions.ConnectionError: Connection closed by server.
@agronholm
Copy link
Contributor

See #2666 (comment) for the explanation why this happens.
PR #2719 would potentially fix this.

@dvora-h
Copy link
Collaborator

dvora-h commented May 1, 2023

@agronholm I don't think #2719 will fix it because it fixes the sync connection and this issue is in the async connection (maybe #2695 will fix it).

@dvora-h
Copy link
Collaborator

dvora-h commented Jul 16, 2023

@cosminacho Can you confirm that the issue solved in #2695?

@schutztj
Copy link

schutztj commented Mar 7, 2024

I am still seeing this issue in 5.02

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

No branches or pull requests

4 participants