Changeset 906
- Timestamp:
- 12/31/05 23:29:26
- Files:
-
- trunk/cherrypy/filters/cachefilter.py (modified) (11 diffs)
- trunk/cherrypy/test/test_cache_filter.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/cherrypy/filters/cachefilter.py
r902 r906 7 7 import basefilter 8 8 9 def defaultCacheKey():10 return cherrypy.request.browser_url11 12 9 13 10 class MemoryCache: 14 15 def __init__(self, key, delay, maxobjsize, maxsize, maxobjects): 16 self.key = key 17 self.delay = delay 18 self.maxobjsize = maxobjsize 19 self.maxsize = maxsize 20 self.maxobjects = maxobjects 21 self.cursize = 0 11 12 def __init__(self): 13 self.clear() 14 self.expirationQueue = Queue.Queue() 15 t = self.expirationThread = threading.Thread(target=self.expireCache, 16 name='expireCache') 17 t.setDaemon(True) 18 t.start() 19 20 def clear(self): 21 """Reset the cache to its initial, empty state.""" 22 22 self.cache = {} 23 self.expirationQueue = Queue.Queue()24 self.expirationThread = threading.Thread(target=self.expireCache, name='expireCache')25 self.expirationThread.setDaemon(True)26 self.expirationThread.start()27 self.totPuts = 028 self.totGets = 029 self.totHits = 030 self.totExpires = 031 self.totNonModified = 032 33 def clear(self):34 """Simply reset the cache to its initial state, all cleared of its values"""35 self.cache.clear()36 23 self.totPuts = 0 37 24 self.totGets = 0 … … 40 27 self.totNonModified = 0 41 28 self.cursize = 0 42 29 30 def _key(self): 31 return cherrypy.config.get("cache_filter.key", cherrypy.request.browser_url) 32 key = property(_key) 33 34 def _maxobjsize(self): 35 return cherrypy.config.get("cache_filter.maxobjsize", 100000) 36 maxobjsize = property(_maxobjsize) 37 38 def _maxsize(self): 39 return cherrypy.config.get("cache_filter.maxsize", 10000000) 40 maxsize = property(_maxsize) 41 42 def _maxobjects(self): 43 return cherrypy.config.get("cache_filter.maxobjects", 1000) 44 maxobjects = property(_maxobjects) 45 43 46 def expireCache(self): 44 47 while True: … … 57 60 # the key may have been deleted elsewhere 58 61 pass 59 62 60 63 def get(self): 61 64 """ … … 65 68 """ 66 69 self.totGets += 1 67 cacheItem = self.cache.get(self.key (), None)70 cacheItem = self.cache.get(self.key, None) 68 71 if cacheItem: 69 72 self.totHits += 1 … … 71 74 else: 72 75 return None 73 76 74 77 def put(self, lastModified, obj): 75 78 # Size check no longer includes header length 76 79 objSize = len(obj[2]) 77 80 totalSize = self.cursize + objSize 81 78 82 # checks if there's space for the object 79 83 if ((objSize < self.maxobjsize) and … … 82 86 # add to the expirationQueue & cache 83 87 try: 84 expirationTime = time.time() + self.delay85 objKey = self.key ()88 expirationTime = time.time() + cherrypy.config.get("cache_filter.delay", 600) 89 objKey = self.key 86 90 self.expirationQueue.put((expirationTime, objSize, objKey)) 91 self.cache[objKey] = (expirationTime, lastModified, obj) 87 92 self.totPuts += 1 88 93 self.cursize += objSize … … 90 95 # can't add because the queue is full 91 96 return 92 self.cache[objKey] = (expirationTime, lastModified, obj)93 97 94 98 … … 98 102 """ 99 103 100 CacheClass = property(lambda self: cherrypy.config.get("cache_filter.cacheClass", MemoryCache))101 key = property(lambda self: cherrypy.config.get("cache_filter.key", defaultCacheKey))102 delay = property(lambda self: cherrypy.config.get("cache_filter.delay", 600))103 maxobjsize = property(lambda self: cherrypy.config.get("cache_filter.maxobjsize", 100000))104 maxsize = property(lambda self: cherrypy.config.get("cache_filter.maxsize", 10000000))105 maxobjects = property(lambda self: cherrypy.config.get("cache_filter.maxobjects", 1000))104 def __init__(self): 105 cache_class = cherrypy.config.get("cache_filter.cacheClass", MemoryCache) 106 cherrypy._cache = cache_class() 107 108 def on_start_resource(self): 109 cherrypy.request.cacheable = False 106 110 107 111 def before_main(self): … … 109 113 return 110 114 111 if not hasattr(cherrypy, '_cache'):112 cherrypy._cache = self.CacheClass(self.key, self.delay,113 self.maxobjsize, self.maxsize, self.maxobjects)114 115 if hasattr(cherrypy, '_clear_cache') and cherrypy._clear_cache == True:116 cherrypy._cache.clear()117 118 115 cacheData = cherrypy._cache.get() 119 cherrypy.request.cacheable = not cacheData120 116 if cacheData: 121 117 # found a hit! check the if-modified-since request header … … 128 124 else: 129 125 # serve it & get out from the request 130 cherrypy.response.status, cherrypy.response.header s, body = obj126 cherrypy.response.status, cherrypy.response.header_list, body = obj 131 127 cherrypy.response.body = body 132 128 raise cherrypy.RequestHandled() 129 else: 130 cherrypy.request.cacheable = True 133 131 134 132 def before_finalize(self): 135 if not (cherrypy.config.get('cache_filter.on', False) and 136 cherrypy.request.cacheable): 133 if not cherrypy.request.cacheable: 137 134 return 138 135 … … 147 144 def on_end_request(self): 148 145 # Close & fix the cache entry after content was fully written 149 if not (cherrypy.config.get('cache_filter.on', False) and 150 cherrypy.request.cacheable): 146 if not cherrypy.request.cacheable: 151 147 return 152 148 153 149 response = cherrypy.response 154 status = response.status155 headers = response.headers156 body = ''.join([chunk for chunk in response._cachefilter_tee])157 158 150 if response.headers.get('Pragma', None) != 'no-cache': 159 151 lastModified = response.headers.get('Last-Modified', None) 160 # saves the cache data 161 cherrypy._cache.put(lastModified, (status, headers, body)) 152 # save the cache data 153 body = ''.join([chunk for chunk in response._cachefilter_tee]) 154 cherrypy._cache.put(lastModified, (response.status, 155 response.header_list, 156 body)) 162 157 163 158 trunk/cherrypy/test/test_cache_filter.py
r902 r906 11 11 12 12 def index(self): 13 c ounter = cherrypy.counter +114 cherrypy.counter =counter15 return "visit #%s" % counter13 cherrypy.counter += 1 14 msg = "visit #%s" % cherrypy.counter 15 return msg 16 16 index.exposed = True 17 17 … … 29 29 30 30 def testCaching(self): 31 # force the cache to be cleared between different tests32 cherrypy._clear_cache = True33 31 for trial in xrange(10): 34 trial = trial + 135 32 self.getPage("/") 36 self.assertBody('visit #%d' % trial) 33 # The response should be the same every time! 34 self.assertBody('visit #1') 37 35 38 36 if __name__ == '__main__': 39 37 helper.testmain() 38

