Skip to content
perrygeo edited this page May 6, 2012 · 9 revisions

Caching goals

  1. avoid database queries
  2. cache expensive feature methods/properties
  3. make sure the cache invalidates itself automatically after db writes (no stale data!)
  4. needs to be turned off easily for dev and testing
  5. Caching templates and views/links (tricky for invalidation?)

View caching

Use djangos builtin cache_page on views that are safe (which ones might that be? workspace?)

Use {% cache %} for safe parts of templates

If username was added to the main map view url, we might be able to cache the construction of the entire first page?

Avoid DB queries

Use an ORM level cache framework:

django-orm-extensions

  • has a low-level orm cache
  • needs a special manager (boo)

johnny cache:

  • magic orm caching
  • invalidates on any write to table (seems safe)
  • memcached-specific? (can it work with Redis backend - maybe)
  • turn off with setting

django-cacheops

  • event-driven invalidation on signals
  • can cache functions as orm calls
  • nice settings options, very automatic
  • more granular (potentially less safe) invalidation
  • requires redis pretty heavily

django-cache-machine

  • uses manager
  • not sure if updated for django 1.4
  • testing was not very promising - didn't work

Caching feature methods

We'll probably do this one custom. This would take the form of a decorator that could be applied to feature methods and properties

class AOI(PolygonFeature):
     ....
     @cacheit
     def some_expensive_thing(self, args):
         ....

The decorator would take the feature instance and construct a key:

 {{global_prefix}}_{{instance uid}}_some_expensive_thing_{{hash of args}}

We'd then query the cache for the key; if it doesn't exist, we'd run the method and write the result to the cache. If the key exists, we just returned the cached value.

@cacheit(0) could indicate we want keys that never expire (for really expensive stuff) or @cacheit(secs) would set an expiration time.

For invalidation, we would listen for a save() or delete() signal on that model and invalidate all keys related to that instance:

 {{global_prefix}}_{{instance uid}}_*

django-redis

  • low-level cache backend for redis
  • provides a keys wildcard search (useful for e.g. invalidating all keys associated with a certain uid)
  • nice stats view page
  • compatible with django-orm-extensions
  • fork of django-redis-cache
  • uncertain how

django-redis-sessions

  • not really caching but could save some DB hits

RELATED

Look into using Redis with celery (http://unfoldthat.com/2011/09/14/try-redis-instead.html)