====================
Ella Cache mechanism
====================

Ella uses `Django's caching mechanism`_ internally to cache individual values.

.. _Django's caching mechanism: http://www.djangoproject.com/documentation/cache/

Cache levels
============

Ella caches content on multiple levels, from the lowest - caching individual
objects (both individual and lists) as they come from the database to caching
entire boxes on the output.  Some time consuming calculations such as the tag
cloud, comments count etc. are cached separately via a `cache_this`__
decorator.

__ `ella.core.cache.cache_this`_

Cached templates
================

Ella provides a template loader (``ella.core.cache.template_loader``) that
caches the template sources.

Cache invalidation
==================

Every cache registers with CacheInvalidator a set of tests, which are then run
against every changed object. If a test passes, the cache is destroyed.

ActiveMQ (via ``stomp`` package) is used to propagate the signals across
multiple frontends.

Methods for caching
===================

ella.core.cache.get_cached_object, get_cached_list
--------------------------------------------------

``get_cached_object`` function is used to cache individual objects, it accepts the ``Model`` or
``ContentType`` instance as first parameter and then any number of keyword
arguments (same as ``QuerySet.get()``. It constructs a cache key using these
parameters. ``get_cached_list`` behaves exactly the same but returns list of
objects matching the lookup parameters instead.

_`ella.core.cache.cache_this`
-----------------------------

``cache_this`` is a decorator used to cache individual function calls.

    def cache_this( key_getter, invalidator=None, timeout=10*60 ):
        ...

Where:

:key_getter:
    is a function that accepts same arguments as the decorated
    function and returns the cache key

:invalidator:
    (optional) is a function that accepts the cache key and
    any arguments accepted by the decorated function and registers any
    invalidation tests may be required

:timeout:
    (default 10 minutes) is time in seconds that defines the
    cache's timeout period.

Example::

    def get_key( func, template_name, template_dirs=None ):
       return 'ella.core.cache.teplate_loader:%d:%s' % ( settings.SITE_ID, template_name, )

    def invalidate_cache( key, template_name, template_dirs=None ):
        from ella.db_templates.models import DbTemplate
        if DbTemplate._meta.installed:
            CACHE_DELETER.register_test( DbTemplate, lambda x: x.name == template_name, key )

    @cache_this( get_key, invalidate_cache, timeout=10*60 )
    def get_cache_teplate( template_name, template_dirs ):
        ...

