From edd72826e6db9a1527bc7417b7fc1313e4c82fe0 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Tue, 6 Jun 2023 16:35:41 -0300 Subject: [PATCH] fix: Prevent errors when memcached object size is exceeded (#5769) * feat: Subclass PyMemcacheCache to tolerate too-large object errors * fix: Use LenientMemcacheCache to prevent search errors * fix: Re-raise errors other than "object too large" --- ietf/settings.py | 6 +++--- ietf/utils/cache.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 ietf/utils/cache.py diff --git a/ietf/settings.py b/ietf/settings.py index bf0c6b1f9..b4801f097 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -729,13 +729,13 @@ CACHE_MIDDLEWARE_KEY_PREFIX = '' # This setting is possibly overridden further down, after the import of settings_local CACHES = { 'default': { - 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', + 'BACKEND': 'ietf.utils.cache.LenientMemcacheCache', 'LOCATION': '127.0.0.1:11211', 'VERSION': __version__, 'KEY_PREFIX': 'ietf:dt', }, 'sessions': { - 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', + 'BACKEND': 'ietf.utils.cache.LenientMemcacheCache', 'LOCATION': '127.0.0.1:11211', # No release-specific VERSION setting. 'KEY_PREFIX': 'ietf:dt', @@ -1242,7 +1242,7 @@ if SERVER_MODE != 'production': CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - #'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + #'BACKEND': 'ietf.utils.cache.LenientMemcacheCache', #'LOCATION': '127.0.0.1:11211', #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 'VERSION': __version__, diff --git a/ietf/utils/cache.py b/ietf/utils/cache.py new file mode 100644 index 000000000..76d1dae54 --- /dev/null +++ b/ietf/utils/cache.py @@ -0,0 +1,19 @@ +# Copyright The IETF Trust 2023, All Rights Reserved +# -*- coding: utf-8 -*- + +from django.core.cache.backends.memcached import PyMemcacheCache +from pymemcache.exceptions import MemcacheServerError + +from .log import log + + +class LenientMemcacheCache(PyMemcacheCache): + """PyMemcacheCache backend that tolerates failed inserts due to object size""" + def set(self, key, value, timeout=None, version=None): + try: + super().set(key, value, timeout, version) + except MemcacheServerError as err: + if "object too large for cache" in str(err): + log(f"Memcache failed to cache large object for {key}") + else: + raise