Login

Multiple cache backend

Author:
isaidyep
Posted:
September 13, 2010
Language:
Python
Version:
1.2
Score:
0 (after 0 ratings)

Sometimes you might find useful to cache a value in different backends. Just put this code in a file named "multicache.py" somewhere in your python path and set it in CACHE_BACKEND setting:

CACHE_BACKEND = 'multicache://?fallback=1&backends=file:///var/tmp/django_cache,locmem://'

Separate the backends settings with commas, the first one will be set as default. Setting fallback to 1 provides fallback to default backend.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from django.core.cache.backends.base import BaseCache
from django.utils.hashcompat import md5_constructor
from django.core.cache import get_cache,parse_backend_uri

class CacheClass(BaseCache,object):
	"""
	A cache backend that serves as a proxy to other backends and provides a fallback system
	>>> cache.set('foo','bar')
	>>> cache.get('foo')
	'bar'
	>>> cache['locmem'].get('foo')
	'bar' #fallback
	>>> cache['locmem'].set('foo','bazzz')
	>>> cache.get('foo')
	'bar'
	>>> cache['locmem'].get('foo')
	'bazzz'
	>>> cache.set_all('foo','bar',20)
	>>> cache.get('foo')
	'bar'
	>>> cache['locmem'].get('foo')
	'bar'
	>>> 
	
	"""
    def __init__(self, _, params):
		
		self.fallback = params.get('fallback',False)

		bs = params.get('backends')
		
		self.backends = {}
		self.default_backend = None
		bs = [b for b in bs.split(',')]
		for backend_uri in bs:
			scheme, host, params = parse_backend_uri(backend_uri)
			cache = get_cache(backend_uri)
			
			if self.default_backend is None:
				self.default_backend = cache
				self.backends[scheme] = cache
			elif self.fallback:
				self.backends[scheme] = fallback_backend(cache,self.default_backend)
			else:
				self.backends[scheme] = cache
		self.set = self.default_backend.set
		self.get = self.default_backend.get
		self.add = self.default_backend.add
		self.delete = self.default_backend.delete
		self.has_key = self.default_backend.has_key
		
    def get_backend(self,scheme):
	"""
	Returns the selected cache backend
	"""
	try:
		return self.backends[scheme]
	except KeyError:
		raise Exception("selected backend isn't set up")
	
    def set_all(self,*args,**kwargs):
	"""
	sets a value in all backends an once
	"""
	for backend in self.backends.itervalues():
		backend.set(*args,**kwargs)

    def __getitem__(self, key):
	return self.get_backend(key)

    def __setitem__(self,key):
	raise Exception("You can't edit the backends manually, use CACHE_BACKEND in settings.py")


class fallback_backend(object):
	"""
	A little class that wraps around a cache backend instance and provides fallback to the default backend
	"""
	def __init__(self,backend,fallback):
		self.backend = backend
		self.fallback = fallback
		self.set = self.backend.set
		self.add = self.backend.add
		self.delete = self.backend.delete
		self.has_key = self.backend.has_key

	def get(self,*args,**kwargs):

		value = self.backend.get(*args,**kwargs)
		if value is None:
			return self.fallback.get(*args,**kwargs)
		else:
			return value

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

stormlifter (on February 24, 2011):

Not completely sure but I think this would need updates for 1.3

#

Please login first before commenting.