Beispiel #1
0
    def __getitem__(self, alias):
        try:
            return getattr(self._caches, alias)
        except AttributeError:
            pass

        if alias not in settings.CACHES:
            raise InvalidCacheBackendError(
                "Could not find config for '%s' in settings.CACHES" % alias)

        cache = _create_cache(alias)
        setattr(self._caches, alias, cache)

        return cache
def _create_cache(backend, **kwargs):
    try:
        # Try to get the CACHES entry for the given profiles name first
        try:
            conf = settings.CACHES[backend]
        except KeyError:
            try:
                # Trying to import the given profiles, in case it's a dotted path
                import_string(backend)
            except ImportError as e:
                raise InvalidCacheBackendError(
                    "Could not find profiles '%s': %s" % (backend, e))
            location = kwargs.pop('LOCATION', '')
            params = kwargs
        else:
            params = {**conf, **kwargs}
            backend = params.pop('BACKEND')
            location = params.pop('LOCATION', '')
        backend_cls = import_string(backend)
    except ImportError as e:
        raise InvalidCacheBackendError("Could not find profiles '%s': %s" %
                                       (backend, e))
    return backend_cls(location, params)
def parse_backend_uri(backend_uri):
    """
    Converts the "backend_uri" into a cache scheme ('db', 'memcached', etc), a
    host and any extra params that are required for the backend. Returns a
    (scheme, host, params) tuple.
    """
    if backend_uri.find(':') == -1:
        raise InvalidCacheBackendError("Backend URI must start with scheme://")
    scheme, rest = backend_uri.split(':', 1)
    if not rest.startswith('//'):
        raise InvalidCacheBackendError("Backend URI must start with scheme://")

    host = rest[2:]
    qpos = rest.find('?')
    if qpos != -1:
        params = dict(parse_qsl(rest[qpos + 1:]))
        host = rest[2:qpos]
    else:
        params = {}
    if host.endswith('/'):
        host = host[:-1]

    return scheme, host, params
Beispiel #4
0
def _create_cache(backend, **kwargs):
    try:
        # Try to get the CACHES entry for the given backend name first
        try:
            conf = settings.CACHES[backend]
        except KeyError:
            try:
                # Trying to import the given backend, in case it's a dotted path
                import_by_path(backend)
            except ImproperlyConfigured as e:
                raise InvalidCacheBackendError("Could not find backend '%s': %s" % (
                    backend, e))
            location = kwargs.pop('LOCATION', '')
            params = kwargs
        else:
            params = conf.copy()
            params.update(kwargs)
            backend = params.pop('BACKEND')
            location = params.pop('LOCATION', '')
        backend_cls = import_by_path(backend)
    except (AttributeError, ImportError, ImproperlyConfigured) as e:
        raise InvalidCacheBackendError(
            "Could not find backend '%s': %s" % (backend, e))
    return backend_cls(location, params)
Beispiel #5
0
def parse_backend_conf(backend, **kwargs):
    """
    Helper function to parse the backend configuration
    that doesn't use the URI notation.
    """
    # Try to get the CACHES entry for the given backend name first
    conf = settings.CACHES.get(backend, None)
    if conf is not None:
        args = conf.copy()
        backend = args.pop('BACKEND')
        location = args.pop('LOCATION', '')
        return backend, location, args
    else:
        # Trying to import the given backend, in case it's a dotted path
        mod_path, cls_name = backend.rsplit('.', 1)
        try:
            mod = importlib.import_module(mod_path)
            backend_cls = getattr(mod, cls_name)
        except (AttributeError, ImportError):
            raise InvalidCacheBackendError("Could not find backend '%s'" % backend)
        location = kwargs.pop('LOCATION', '')
        return backend, location, kwargs
    raise InvalidCacheBackendError(
        "Couldn't find a cache backend named '%s'" % backend)
    def __getitem__(self, alias):
        try:
            return self._caches.caches[alias]
        except AttributeError:
            self._caches.caches = {}
        except KeyError:
            pass

        if alias not in settings.CACHES:
            raise InvalidCacheBackendError(
                "Could not find config for '%s' in settings.CACHES" % alias)

        cache = _create_cache(alias)
        self._caches.caches[alias] = cache
        return cache
Beispiel #7
0
 def __init__(self, server, params):
     import warnings
     warnings.warn(
         "memcached.CacheClass has been split into memcached.MemcachedCache and memcached.PyLibMCCache. Please update your cache backend setting.",
         DeprecationWarning
     )
     try:
         import memcache
     except ImportError:
         raise InvalidCacheBackendError(
             "Memcached cache backend requires either the 'memcache' or 'cmemcache' library"
             )
     super(CacheClass, self).__init__(server, params,
                                      library=memcache,
                                      value_not_found_exception=ValueError)
def get_cache(backend, **kwargs):
    """
    Function to load a cache backend dynamically. This is flexible by design
    to allow different use cases:

    To load a backend with the old URI-based notation::

        cache = get_cache('locmem://')

    To load a backend that is pre-defined in the settings::

        cache = get_cache('default')

    To load a backend with its dotted import path,
    including arbitrary options::

        cache = get_cache('django.core.cache.backends.memcached.MemcachedCache', **{
            'LOCATION': '127.0.0.1:11211', 'TIMEOUT': 30,
        })

    """
    try:
        if '://' in backend:
            # for backwards compatibility
            backend, location, params = parse_backend_uri(backend)
            if backend in BACKENDS:
                backend = 'django.core.cache.backends.%s' % BACKENDS[backend]
            params.update(kwargs)
            mod = importlib.import_module(backend)
            backend_cls = mod.CacheClass
        else:
            backend, location, params = parse_backend_conf(backend, **kwargs)
            mod_path, cls_name = backend.rsplit('.', 1)
            mod = importlib.import_module(mod_path)
            backend_cls = getattr(mod, cls_name)
    except (AttributeError, ImportError) as e:
        raise InvalidCacheBackendError("Could not find backend '%s': %s" %
                                       (backend, e))
    cache = backend_cls(location, params)
    # Some caches -- python-memcached in particular -- need to do a cleanup at the
    # end of a request cycle. If the cache provides a close() method, wire it up
    # here.
    if hasattr(cache, 'close'):
        signals.request_finished.connect(cache.close)
    return cache
Beispiel #9
0
 def __init__(self, server, params):
     try:
         import cmemcache as memcache
         import warnings
         warnings.warn(
             "Support for the 'cmemcache' library has been deprecated. Please use python-memcached or pyblimc instead.",
             DeprecationWarning)
     except ImportError:
         try:
             import memcache
         except:
             raise InvalidCacheBackendError(
                 "Memcached cache backend requires either the 'memcache' or 'cmemcache' library"
             )
     super(CacheClass, self).__init__(server,
                                      params,
                                      library=memcache,
                                      value_not_found_exception=ValueError)
Beispiel #10
0
def parse_backend_conf(backend, **kwargs):
    """
    Helper function to parse the backend configuration
    that doesn't use the URI notation.
    """
    # Try to get the CACHES entry for the given backend name first
    conf = settings.CACHES.get(backend, None)
    if conf is not None:
        args = conf.copy()
        args.update(kwargs)
        backend = args.pop('BACKEND')
        location = args.pop('LOCATION', '')
        return backend, location, args
    else:
        try:
            # Trying to import the given backend, in case it's a dotted path
            import_by_path(backend)
        except ImproperlyConfigured as e:
            raise InvalidCacheBackendError("Could not find backend '%s': %s" %
                                           (backend, e))
        location = kwargs.pop('LOCATION', '')
        return backend, location, kwargs
Beispiel #11
0
def get_cache(backend, **kwargs):
    """
    Function to load a cache backend dynamically. This is flexible by design
    to allow different use cases:

    To load a backend with the old URI-based notation::

        cache = get_cache('locmem://')

    To load a backend that is pre-defined in the settings::

        cache = get_cache('default')

    To load a backend with its dotted import path,
    including arbitrary options::

        cache = get_cache('django.core.cache.backends.memcached.MemcachedCache', **{
            'LOCATION': '127.0.0.1:11211', 'TIMEOUT': 30,
        })

    """
    try:
        if '://' in backend:
            # for backwards compatibility
            backend, location, params = parse_backend_uri(backend)
            if backend in BACKENDS:
                backend = 'django.core.cache.backends.%s' % BACKENDS[backend]
            params.update(kwargs)
            mod = importlib.import_module(backend)
            backend_cls = mod.CacheClass
        else:
            backend, location, params = parse_backend_conf(backend, **kwargs)
            mod_path, cls_name = backend.rsplit('.', 1)
            mod = importlib.import_module(mod_path)
            backend_cls = getattr(mod, cls_name)
    except (AttributeError, ImportError), e:
        raise InvalidCacheBackendError(
            "Could not find backend '%s': %s" % (backend, e))
def parse_backend_uri(backend_uri):
    """
    Converts the "backend_uri" into a host and any extra params that are
    required for the backend. Returns a (host, params) tuple.
    """
    backend_uri_sliced = backend_uri.split('://')
    if len(backend_uri_sliced) > 2:
        raise InvalidCacheBackendError("Backend URI can't have more than one scheme://")
    elif len(backend_uri_sliced) == 2:
        rest = backend_uri_sliced[1]
    else:
        rest = backend_uri_sliced[0]

    host = rest[2:]
    qpos = rest.find('?')
    if qpos != -1:
        params = dict(parse_qsl(rest[qpos+1:]))
        host = rest[2:qpos]
    else:
        params = {}
    if host.endswith('/'):
        host = host[:-1]

    return host, params
Beispiel #13
0
"Memcached cache backend"

from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
from django.utils.encoding import smart_unicode, smart_str

try:
    import cmemcache as memcache
except ImportError:
    try:
        import memcache
    except:
        raise InvalidCacheBackendError(
            "Memcached cache backend requires either the 'memcache' or 'cmemcache' library"
        )


class CacheClass(BaseCache):
    def __init__(self, server, params):
        BaseCache.__init__(self, params)
        self._cache = memcache.Client(server.split(';'))

    def add(self, key, value, timeout=0):
        self._cache.add(key.encode('ascii', 'ignore'), value, timeout
                        or self.default_timeout)

    def get(self, key, default=None):
        val = self._cache.get(smart_str(key))
        if val is None:
            return default
        else:
            if isinstance(val, basestring):
Beispiel #14
0
from django.core.cache.backends.base import (
    BaseCache,
    DEFAULT_TIMEOUT,
    InvalidCacheBackendError,
)
from django.core.exceptions import ImproperlyConfigured

try:
    import redis
except ImportError:
    raise InvalidCacheBackendError(
        "Redis cache backend requires the 'redis-py' library")

from redis.connection import DefaultParser

from redis_cache.connection import pool
from redis_cache.utils import (CacheKey, get_servers, parse_connection_kwargs,
                               import_class)

from functools import wraps


def get_client(write=False):
    def wrapper(method):
        @wraps(method)
        def wrapped(self, key, *args, **kwargs):
            version = kwargs.pop('version', None)
            client = self.get_client(key, write=write)
            key = self.make_key(key, version=version)
            return method(self, client, key, *args, **kwargs)
Beispiel #15
0
"""
django_casscache
~~~~~~~~~~~~~~~~

:copyright: (c) 2013 by Matt Robenolt.
:license: BSD, see LICENSE for more details.
"""

from django.core.cache.backends.base import InvalidCacheBackendError
from django.core.cache.backends.memcached import BaseMemcachedCache

try:
    import casscache
except ImportError:
    raise InvalidCacheBackendError('Could not import casscache')

__all__ = ['CasscacheCache']


class CasscacheCache(BaseMemcachedCache):
    "An implementation of a cache binding using casscache"

    def __init__(self, server, params):
        super(CasscacheCache,
              self).__init__(server,
                             params,
                             library=casscache,
                             value_not_found_exception=ValueError)

    @property
    def _cache(self):
Beispiel #16
0
import logging

from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError

from hazelcast_cache.utils import import_class, CacheKey

try:
    import hazelcast
except ImportError:
    raise InvalidCacheBackendError(
        "Hazelcast cache backend requires the 'hazelcast-python-client' library"
    )

from functools import wraps

logging.basicConfig(
    format='%(asctime)s%(msecs)03d [%(name)s] %(levelname)s: %(message)s',
    datefmt="%H:%M%:%S,")
logging.getLogger().setLevel(logging.INFO)
logger = logging.getLogger("main")

DEFAULT_TIMEOUT = 1000


def get_client(write=False):
    def wrapper(method):
        @wraps(method)
        def wrapped(self, key, *args, **kwargs):
            version = kwargs.pop('version', None)
            client = self.get_client(key, write=write)
            key = self.make_key(key, version=version)
Beispiel #17
0
from django.core.cache.backends import memcached
from django.core.cache.backends.base import InvalidCacheBackendError
from django.utils.encoding import smart_str

from cachebot.backends import version_key_decorator
from cachebot.logger import CacheLogger

try:
    import cmemcache as memcache
except ImportError:
    try:
        import memcache
    except:
        raise InvalidCacheBackendError(
            "libmemcached backend requires either the 'python-memcached' or 'cmemcached' library"
        )


class CacheClass(memcached.CacheClass):
    def __init__(self, *args, **kwargs):
        super(CacheClass, self).__init__(*args, **kwargs)
        self._logger = CacheLogger()

    @version_key_decorator
    def add(self, key, value, timeout=None):
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        if timeout is None:
            timeout = self.default_timeout
        return self._cache.add(smart_str(key), value, timeout)
Beispiel #18
0
            # for backwards compatibility
            backend, location, params = parse_backend_uri(backend)

            if backend in BACKENDS:
                backend = 'django.core.cache.backends.%s' % BACKENDS[backend]

            params.update(kwargs)
            mod = importlib.import_module(backend)
            backend_cls = mod.CacheClass 厉害, 每个模块中都有一个 CacheClass
        else:
            backend, location, params = parse_backend_conf(backend, **kwargs)
            mod_path, cls_name = backend.rsplit('.', 1)
            mod = importlib.import_module(mod_path)
            backend_cls = getattr(mod, cls_name)

    except (AttributeError, ImportError) as e:
        raise InvalidCacheBackendError(
            "Could not find backend '%s': %s" % (backend, e))

    cache = backend_cls(location, params)

    # Some caches -- python-memcached in particular -- need to do a cleanup at the
    # end of a request cycle. If the cache provides a close() method, wire it up
    # here.
    if hasattr(cache, 'close'):
        signals.request_finished.connect(cache.close) 不懂 
    return cache

cache = get_cache(DEFAULT_CACHE_ALIAS)

Beispiel #19
0
    from django.utils import importlib
except ImportError:
    import importlib

try:
    import pylibmc as memcache
    NotFoundError = memcache.NotFound
    using_pylibmc = True
except ImportError:
    using_pylibmc = False
    try:
        import memcache
        NotFoundError = ValueError
    except ImportError:
        raise InvalidCacheBackendError(
            'Memcached cache backend requires ' +
            'either the "pylibmc" or "memcache" library')

# Flavor is used amongst multiple apps to differentiate the "flavor" of the
# environment. Examples of flavors are 'prod', 'staging', 'dev', and 'test'.
FLAVOR = getattr(settings, 'FLAVOR', '')

CACHE_VERSION = str(getattr(settings, 'CACHE_VERSION', 1))
CACHE_BEHAVIORS = getattr(settings, 'CACHE_BEHAVIORS', {'hash': 'crc'})
CACHE_KEY_MODULE = getattr(settings, 'CACHE_KEY_MODULE', 'newcache')
CACHE_HERD_TIMEOUT = getattr(settings, 'CACHE_HERD_TIMEOUT', 60)


class Marker(object):
    pass
Beispiel #20
0
def memcache_info(request):
    """
    View to display memcache statistics

    Only works with Django 1.3+ using the settings.CACHES setting.
    """
    try:
        # Check if memcache is used:
        hosts = []

        for backend in settings.CACHES.values():
            if backend[
                    "BACKEND"] == 'django.core.cache.backends.memcached.MemcachedCache':
                hosts.extend(backend["LOCATION"])

        if not hosts:
            raise InvalidCacheBackendError(
                "You are not using memcache as cache backend - %s" %
                settings.CACHES)

        # Import module
        try:
            import memcache
        except ImportError:
            raise InvalidCacheBackendError(
                "Statistics only works with python-memcache and not e.g. the cmemcache module."
            )

        # Retrieve statistics from servers
        mc = memcache.Client(hosts, debug=0)
        stats = mc.get_stats()

        # Regroup statistics for display purposes.
        header = ['']
        keys = []

        for host in stats:
            header.append(host[0])
            keys += host[1].keys()

        keys = list(set(keys))
        keys.sort()
        rows = []

        for k in keys:
            r = [k]
            for host in stats:
                try:
                    r.append(host[1][k])
                except KeyError:
                    r.append("")

            rows.append(r)

        table = [header] + rows

        return render(
            request, 'admin/cache/memcache_info.html', {
                'title': 'Memcached statistics',
                'has_memcache': True,
                'stats': table,
            })
    except InvalidCacheBackendError, e:
        return render(
            request, 'admin/cache/memcache_info.html', {
                'title': 'Memcached statistics',
                'has_memcache': False,
                'error_message': unicode(e),
            })
Beispiel #21
0
from threading import local

from django.core.cache.backends.base import InvalidCacheBackendError
from django.core.cache.backends.memcached import BaseMemcachedCache

try:
    from . import client
except ImportError:
    raise InvalidCacheBackendError('Could not import pymemcache.')


class PyMemcacheCache(BaseMemcachedCache):
    """An implementation of a cache binding using pymemcache."""
    def __init__(self, server, params):
        self._local = local()
        super(PyMemcacheCache, self).__init__(
            server,
            params,
            library=client,
            value_not_found_exception=KeyError,
        )

    @property
    def _cache(self):
        client = getattr(self._local, 'client', None)
        if client:
            return client

        client = self._lib.Client(self._servers, **self._options)
        if self._options:
            client.behaviors = self._options
from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
from django.conf import settings

try:
    import cPickle as pickle
except ImportError:
    import pickle

try:
    import uwsgi
except ImportError:
    if getattr(settings, "UWSGI_CACHE_FALLBACK", True):
        uwsgi = None
    else:
        raise InvalidCacheBackendError(
            "You're not running under uWSGI ! "
            "Set UWSGI_CACHE_FALLBACK=True in settings if you want to fallback "
            "to LocMemCache.")

if uwsgi:

    class UWSGICache(BaseCache):
        def __init__(self, server, params):
            BaseCache.__init__(self, params)
            self._cache = uwsgi
            self._server = server

        def exists(self, key):
            return self._cache.cache_exists(stringify(key), self._server)

        def add(self, key, value, timeout=None, version=None):
            if timeout is None:
Beispiel #23
0
Unlike the default Django caching backends, this backend lets you pass 0 as a
timeout, which translates to an infinite timeout in memcached.
"""
import logging
import warnings
from threading import local

from django.conf import settings
from django.core.cache.backends.base import InvalidCacheBackendError
from django.core.cache.backends.memcached import BaseMemcachedCache, DEFAULT_TIMEOUT

try:
    import pylibmc
    from pylibmc import Error as MemcachedError
except ImportError:
    raise InvalidCacheBackendError('Could not import pylibmc.')

log = logging.getLogger('django.pylibmc')

MIN_COMPRESS_LEN = getattr(settings, 'PYLIBMC_MIN_COMPRESS_LEN', 0)  # Disabled
if MIN_COMPRESS_LEN > 0 and not pylibmc.support_compression:
    MIN_COMPRESS_LEN = 0
    warnings.warn('A minimum compression length was provided but pylibmc was '
                  'not compiled with support for it.')

COMPRESS_LEVEL = getattr(settings, 'PYLIBMC_COMPRESS_LEVEL',
                         -1)  # zlib.Z_DEFAULT_COMPRESSION
if not COMPRESS_LEVEL == -1:
    if not pylibmc.support_compression:
        warnings.warn('A compression level was provided but pylibmc was '
                      'not compiled with support for it.')