channels
channels copied to clipboard
Task was destroyed but it is pending!
Hi! Regularly in the Sentry I'm getting this message:
task: <Task pending name='Task-840' coro=<RedisConnection._read_data() done, defined at /usr/local/lib/python3.9/site-packages/aioredis/connection.py:180> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7f417b0ee520>()]> cb=[RedisConnection.__init__.<locals>.<lambda>() at /usr/local/lib/python3.9/site-packages/aioredis/connection.py:168]>
Perhaps, problem in the channels-redis
package, but I'm not sure.
Versions:
channels = "^3.0.5"
channels-redis = "^3.4.1"
uvicorn = {extras = ["standard"], version = "^0.18.3"}
wsproto = "^1.2.0"
consumer.py:
class ConnectionConsumer(AsyncWebsocketConsumer):
async def connect(self):
""" Called on connection """
try:
await self.accept()
except (ConnectionClosedError, ConnectionClosedOK, TypeError, RuntimeError):
await self.close()
async def receive(self, text_data=None, bytes_data=None):
""" Receive a message and send it back """
text_data_json = json.loads(text_data)
message = text_data_json.get('message', None)
try:
await self.send(text_data=json.dumps({'message': message}))
except (ConnectionClosedError, ConnectionClosedOK, TypeError, RuntimeError):
await self.close()
settings.py
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [f"redis://{env('REDIS_HOST')}:{env('REDIS_PORT')}/{env('REDIS_WEBSOCKETS_DB')}"]
},
},
}
For us, these show up in Sentry when we do a deployment and Heroku swaps over the dynos and traffic. My best guess has been that Heroku does not wait to cleanup all the tasks and just slams the door while things are still inflight (a cleaner transfer of power is of course on that infinite todo list).
Unsure on what hosting/infrastructure being run, but the timing of the errors strongly coincided with changes unrelated to the code but where it was running.
If memory serves me this was a bug in aioredis~=1.3
which may have been fixed in aioredis>=2.0
. Unfortunately channels-redis<4.0
doesn't support the later version and channels-redis>=4.0
was migrated to the async implementation in redis-py>=4.2
(which is the successor to aioredis
).
At this stage I'd recommend trying out channels>=4.0
, channels-redis>=4.0
and redis>=4.3
- a lot has changed and it's highly unlikely that anything is going to be done to address this issue in older versions.
Yep, thanks @ngnpope. If this reproduces on the latest versions we can have a look.
(If this is a shutdown message, it's on the list for the next phase to tighten up checking for these and making sure we're exiting tasks cleanly where possible.)