Skip to content

Redis UTF-8 cause hard to debug issue on group_sendΒ #222

Open
@insspb

Description

@insspb

All code is reproducible in multichat example app with last django and channels_redis.

It is possible to make settings.py configuration like this:

CHANNEL_LAYERS = {
    "default": {
        # This example app uses the Redis channel layer implementation channels_redis
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [
                "redis://redis:6379/0?encoding=utf-8"
            ]
        },
    },
}

Let's take code that will create fake group and send message there.
Code example for pycharm django console.

from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer

layer = get_channel_layer()
add = async_to_sync(layer.group_add)
send = async_to_sync(layer.group_send)
res1 = add("some", "random")
res2 = send("some", {"message": "message",})

You will get this traceback:

Traceback (most recent call last):
  File "<input>", line 8, in <module>
  File "/home/insspb/.venvs/quick/lib/python3.7/site-packages/asgiref/sync.py", line 139, in __call__
    return call_result.result()
  File "/usr/lib/python3.7/concurrent/futures/_base.py", line 428, in result
    return self.__get_result()
  File "/usr/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
  File "/home/insspb/.venvs/quick/lib/python3.7/site-packages/asgiref/sync.py", line 204, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "/home/insspb/.venvs/quick/lib/python3.7/site-packages/channels_redis/core.py", line 634, in group_send
    x.decode("utf8") for x in await connection.zrange(key, 0, -1)
  File "/home/insspb/.venvs/quick/lib/python3.7/site-packages/channels_redis/core.py", line 634, in <listcomp>
    x.decode("utf8") for x in await connection.zrange(key, 0, -1)
AttributeError: 'str' object has no attribute 'decode'

And it is very hard to guess that problem in connection string. Because item in redis will be created.

If replace connection code with same, but without encoding mention all will work without any issues.

CHANNEL_LAYERS = {
    "default": {
        # This example app uses the Redis channel layer implementation channels_redis
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [
                "redis://redis:6379/0"
            ]
        },
    },
}

Here run with this string, without any issue.

import sys; print('Python %s on %s' % (sys.version, sys.platform))
import django; print('Django %s' % django.get_version())
sys.path.extend(['/home/insspb/git/quick', '/snap/pycharm-professional/213/plugins/python/helpers/pycharm', '/snap/pycharm-professional/213/plugins/python/helpers/pydev'])
if 'setup' in dir(django): django.setup()
import django_manage_shell; django_manage_shell.run("/home/insspb/git/quick")
PyDev console: starting.
Python 3.7.9 (default, Aug 18 2020, 06:22:45) 
[GCC 7.5.0] on linux
Django 3.1
from asgiref.sync import async_to_sync
... from channels.layers import get_channel_layer
... 
... layer = get_channel_layer()
... add = async_to_sync(layer.group_add)
... send = async_to_sync(layer.group_send)
... res1 = add("some", "random")
... res2 = send("some", {"message": "message",})
... print("Done without issues")
Done without issues

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions