﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22845	Memcached backend handles infinite (None) timeout defined in default settings improperly	Althalus	nobody	"#9595 introduced a way to use `None` as way to set infinite memcached timeout.
It works fine while you specify this timeout explicitly like `cache.set('key', 'val', None)`.
But it works wrong if you define it as a default cache timeout in django.conf.settings.CACHES.

Consider the following parts:

{{{#!python
# base.py
class BaseCache(object):
    def __init__(self, params):
        timeout = params.get('timeout', params.get('TIMEOUT', 300))
        if timeout is not None:
            try:
                timeout = int(timeout)
            except (ValueError, TypeError):
                timeout = 300
        self.default_timeout = timeout
}}}

{{{#!python
    # memcached.py
    def get_backend_timeout(self, timeout=DEFAULT_TIMEOUT):
        """"""
        Memcached deals with long (> 30 days) timeouts in a special
        way. Call this function to obtain a safe value for your timeout.
        """"""
        if timeout == DEFAULT_TIMEOUT:
            return self.default_timeout

        if timeout is None:
            # Using 0 in memcache sets a non-expiring timeout.
            return 0
        elif int(timeout) == 0:
            # Other cache backends treat 0 as set-and-expire. To achieve this
            # in memcache backends, a negative timeout must be passed.
            timeout = -1

        if timeout > 2592000:  # 60*60*24*30, 30 days
            # See http://code.google.com/p/memcached/wiki/FAQ
            # ""You can set expire times up to 30 days in the future. After that
            # memcached interprets it as a date, and will expire the item after
            # said date. This is a simple (but obscure) mechanic.""
            #
            # This means that we have to switch to absolute timestamps.
            timeout += int(time.time())
        return int(timeout)
}}}

As you can see special handling of `None`, `0` and long timeouts is performed in `get_backend_timeout`.
But it only handles explicit timeouts. For default timeout there's no special processing while it's needed - timeout is just taken from `BaseCache.__init__`.

So when trying to set `None` as default timeout django just transfers it to the memcached driver and which leads to errors.
Also when timeout is set to some high value (more then 30 days) it is not converted to timestamp as memcached requires. In my case it caused all my cache entries to expire immidiately."	Bug	closed	Core (Cache system)	dev	Release blocker	fixed	cache, memcached		Accepted	1	0	0	0	0	0
