Is there a way to ignore Cache errors in Django?

2019-06-17 06:45发布

I've just set our development Django site to use redis for a cache backend and it was all working fine. I brought down redis to see what would happen, and sure enough Django 404's due to cache backend behaviour. Either the Connection was refused, or various other errors.

Is there any way to instruct Django to ignore Cache errors, and continue processing the normal way? It seems weird that caching is a performance optimization, but can bring down an entire site if it fails.

I tried to write a wrapper around the backend like so:

class CacheClass(redis_backend.CacheClass):
    """ Wraps the desired Cache, and falls back to global_settings default on init failure """
    def __init__(self, server, params):
        try:
            super(CacheClass, self).__init__(server, params)
        except Exception:
            from django.core import cache as _
            _.cache = _.get_cache('locmem://')

But that won't work, since I'm trying to set the cache type in the call that sets the cache type. It's all a very big mess.

So, is there any easy way to swallow cache errors? Or to set the default cache backend on failure?

3条回答
一夜七次
2楼-- · 2019-06-17 07:25

It doesn't look like there is any good way to do what I want, without writing error handing directly into the methods that the cache backend support. Even if init of the backend fails, some backends will only throw errors on first access to the backend.

What I've done is modified the backend to wrap all methods with error handling that's conditional on a param passed to the constructor. Not as nice as I'd like.. but it's the least intrusive.

Nothing needs to change in the calling code, so the interface, if you will, is maintained.

查看更多
Viruses.
3楼-- · 2019-06-17 07:29

Look at django-cache-fallback:

https://pypi.python.org/pypi/django-cache-fallback/0.2.1

CACHES = {
    # Set default cache to FallbackCache
    'default': {
        'BACKEND': 'cache_fallback.FallbackCache',
    },
    # Your production main cache (Redis, for example)
    'main_cache': {
        'BACKEND': 'redis_lock.django_cache.RedisCache',
        'LOCATION': redis_url,
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        },
        'TIMEOUT': 500,
    },
    # Use dummy cache to ignore main cache errors and get data from DB
    'fallback_cache': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}
查看更多
Summer. ? 凉城
4楼-- · 2019-06-17 07:50

I haven't used it, but here's a Django snippet that claims to provide a cache backend with a fallback feature: http://djangosnippets.org/snippets/2193/

查看更多
登录 后发表回答