diff --git a/api/Dockerfile b/api/Dockerfile index 036330368..7a8526e83 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.11 +FROM alpine:3.10 RUN \ echo 'installing dependencies' && \ diff --git a/api/config/settings/common.py b/api/config/settings/common.py index a2cbfd64e..45854515c 100644 --- a/api/config/settings/common.py +++ b/api/config/settings/common.py @@ -544,7 +544,7 @@ CHANNEL_LAYERS = { } CACHES["default"]["OPTIONS"] = { - "CLIENT_CLASS": "django_redis.client.DefaultClient", + "CLIENT_CLASS": "funkwhale_api.common.cache.RedisClient", "IGNORE_EXCEPTIONS": True, # mimics memcache behavior. # http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior } diff --git a/api/funkwhale_api/common/cache.py b/api/funkwhale_api/common/cache.py new file mode 100644 index 000000000..d98b73797 --- /dev/null +++ b/api/funkwhale_api/common/cache.py @@ -0,0 +1,29 @@ +import logging + +from django_redis.client import default + +logger = logging.getLogger(__name__) + + +class RedisClient(default.DefaultClient): + def get(self, key, default=None, version=None, client=None): + try: + return super().get(key, default=None, version=None, client=None) + except ValueError as e: + if "unsupported pickle protocol" in str(e): + # pickle deserialization error + logger.warn("Error while deserializing pickle value from cache") + return default + else: + raise + + def get_many(self, *args, **kwargs): + try: + return super().get_many(*args, **kwargs) + except ValueError as e: + if "unsupported pickle protocol" in str(e): + # pickle deserialization error + logger.warn("Error while deserializing pickle value from cache") + return {} + else: + raise diff --git a/api/funkwhale_api/common/channels.py b/api/funkwhale_api/common/channels.py index d9422f6fa..4dcf59938 100644 --- a/api/funkwhale_api/common/channels.py +++ b/api/funkwhale_api/common/channels.py @@ -8,6 +8,7 @@ from django.core.serializers.json import DjangoJSONEncoder logger = logging.getLogger(__name__) channel_layer = get_channel_layer() group_add = async_to_sync(channel_layer.group_add) +group_discard = async_to_sync(channel_layer.group_discard) def group_send(group, event): diff --git a/api/funkwhale_api/common/consumers.py b/api/funkwhale_api/common/consumers.py index 48c318638..9db4138ff 100644 --- a/api/funkwhale_api/common/consumers.py +++ b/api/funkwhale_api/common/consumers.py @@ -14,7 +14,11 @@ class JsonAuthConsumer(JsonWebsocketConsumer): def accept(self): super().accept() - for group in self.groups: - channels.group_add(group, self.channel_name) - for group in self.scope["user"].get_channels_groups(): + groups = self.scope["user"].get_channels_groups() + self.groups + for group in groups: channels.group_add(group, self.channel_name) + + def disconnect(self, close_code): + groups = self.scope["user"].get_channels_groups() + self.groups + for group in groups: + channels.group_discard(group, self.channel_name)