1''' 2Provides several CacheStore backends for Cheetah's caching framework. The 3methods provided by these classes have the same semantics as those in the 4python-memcached API, except for their return values: 5 6set(key, val, time=0) 7 set the value unconditionally 8add(key, val, time=0) 9 set only if the server doesn't already have this key 10replace(key, val, time=0) 11 set only if the server already have this key 12get(key, val) 13 returns val or raises a KeyError 14delete(key) 15 deletes or raises a KeyError 16''' 17import time 18 19class Error(Exception): 20 pass 21 22class AbstractCacheStore(object): 23 24 def set(self, key, val, time=None): 25 raise NotImplementedError 26 27 def add(self, key, val, time=None): 28 raise NotImplementedError 29 30 def replace(self, key, val, time=None): 31 raise NotImplementedError 32 33 def delete(self, key): 34 raise NotImplementedError 35 36 def get(self, key): 37 raise NotImplementedError 38 39class MemoryCacheStore(AbstractCacheStore): 40 def __init__(self): 41 self._data = {} 42 43 def set(self, key, val, time=0): 44 self._data[key] = (val, time) 45 46 def add(self, key, val, time=0): 47 if key in self._data: 48 raise Error('a value for key %r is already in the cache'%key) 49 self._data[key] = (val, time) 50 51 def replace(self, key, val, time=0): 52 if key in self._data: 53 raise Error('a value for key %r is already in the cache'%key) 54 self._data[key] = (val, time) 55 56 def delete(self, key): 57 del self._data[key] 58 59 def get(self, key): 60 (val, exptime) = self._data[key] 61 if exptime and time.time() > exptime: 62 del self._data[key] 63 raise KeyError(key) 64 else: 65 return val 66 67 def clear(self): 68 self._data.clear() 69 70class MemcachedCacheStore(AbstractCacheStore): 71 servers = ('127.0.0.1:11211') 72 def __init__(self, servers=None, debug=False): 73 if servers is None: 74 servers = self.servers 75 from memcache import Client as MemcachedClient 76 self._client = MemcachedClient(servers, debug) 77 78 def set(self, key, val, time=0): 79 self._client.set(key, val, time) 80 81 def add(self, key, val, time=0): 82 res = self._client.add(key, val, time) 83 if not res: 84 raise Error('a value for key %r is already in the cache'%key) 85 self._data[key] = (val, time) 86 87 def replace(self, key, val, time=0): 88 res = self._client.replace(key, val, time) 89 if not res: 90 raise Error('a value for key %r is already in the cache'%key) 91 self._data[key] = (val, time) 92 93 def delete(self, key): 94 res = self._client.delete(key, time=0) 95 if not res: 96 raise KeyError(key) 97 98 def get(self, key): 99 val = self._client.get(key) 100 if val is None: 101 raise KeyError(key) 102 else: 103 return val 104 105 def clear(self): 106 self._client.flush_all() 107