skip to Main Content

We have Django Channels coupled with uvicorn and azure redis instance. Our sentry is getting swamped with errors such as:

Exception in ASGI application
 
ssd.consumers in disconnect

Error UNKNOWN while writing to socket. Connection lost.

The exception is thrown in asyncio/streams.py file as shown on example
Snippet that throws exception.

My main issue is that I have no idea if redis cuts this connection, or server is not keen to keep it? Any hints appreciated. I haven’t observed such behaviour on local instance of redis. We opearte on following packages:

Django = "~4.2"
redis = "^4.3.1"
channels = {extras = ["daphne"], version = "^4.0.0"}
channels-redis = "^4.1.0"
uvicorn = {extras = ["standard"], version = "^0.24.0.post1"}

It’s worth to point that it works majority of the times, websockets are operational, sometimes it just randomly throw an exception mentioned above.

2

Answers


  1. Chosen as BEST ANSWER

    Apparently there is more config in channels_redis lib that can be specified which is not explicitly stated in documentation. Since Azure Cache For Redis is not liberal one it was timing out idle connections. Changing my setting to this one solved issue:

        CHANNEL_LAYERS = {
            "default": {
                "BACKEND": "channels_redis.core.RedisChannelLayer",
                "CONFIG": {
                    "hosts": [
                        { # specifying host as dict with additional keys for redis-py client was a key to solve it.
                            "address": CHANNELS_REDIS_URL,
                            "retry_on_timeout": True,
                            "health_check_interval": 1,
                            "socket_keepalive": True,
                        }
                    ],
                    "capacity": 1500,
                    "expiry": 5,
                },
            },
        }
    

  2. redis uses the asyncio package to establish a connection over the websocket and to establish a asynchronous data pipeline between the client and the server. The server is using different functions in the asyncio package in order to communicate with the client, and most of them work fine. However, if you check PyPi for channels-redis, you will see that this library is failing tests and is unstable.

    However, you should be able to get it running stable. Make sure you are running Python 3.8+ as is required for redis as shown on its PyPi page. As I explained, channels-redis might be unstable in some regard, but I think that is mostly unstable in finding the right series of packages that are completely compatible and call the right function names as they seem to change in libraries. I recommend using something new but not too old that has good library support, right now I suggest Python 3.11.8.

    When you install/update the packages using pip, you should install them in the order that the dependencies require and they should install a version of the package that compatible with the other packages. This is where you might want to test the stability of each version and roll back channels-redis to see if anything changes, checking with redis version and release date on PyPi.

    When you install the latest Django for Python 3.11.8, you should then install redis, and channels-redis, and more than likely everything will be working. But it may be worth taking note of your current package versions or using a test server altogether if you are in production.

    pip install Django --upgrade
    pip install redis --upgrade
    pip install channels-redis --upgrade
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search