Just as reminder, this is a pending patch against SVN trunk to add an easy page-wide caching with timeout or persistent. Index: Nevow/nevow/rend.py =================================================================== --- Nevow/nevow/rend.py (revision 1399) +++ Nevow/nevow/rend.py (working copy) @@ -30,6 +30,7 @@ from nevow import flat from nevow.util import log from nevow import util +from nevow import url import formless from formless import iformless @@ -405,6 +406,8 @@ self.children[name] = child +_CACHE = {} + class Page(Fragment, ConfigurableFactory, ChildLookupMixin): """A page is the main Nevow resource and renders a document loaded via the document factory (docFactory). @@ -418,8 +421,37 @@ afterRender = None addSlash = None + cache = False + lifetime = -1 + __lastCacheRendering = 0 + flattenFactory = lambda self, *args: flat.flattenFactory(*args) + def hasCache(self, ctx): + if not self.cache: + return + + _now = now() # run gettimeofday only once + timeout = _now > self.__lastCacheRendering + self.lifetime and \ + self.lifetime >= 0 + c = self.lookupCache(ctx) + if timeout or c is None: + # stop other renders + self.__lastCacheRendering = _now + c = None + return c + def cacheRendered(self, ctx, c): + if not self.cache: + return + # overwrite the deferred with the data + self.storeCache(ctx, c) + def cacheIDX(self, ctx): + return str(url.URL.fromContext(ctx)) + def storeCache(self, ctx, c): + _CACHE[self.cacheIDX(ctx)] = c + def lookupCache(self, ctx): + return _CACHE.get(self.cacheIDX(ctx)) + def renderHTTP(self, ctx): if self.beforeRender is not None: return util.maybeDeferred(self.beforeRender,ctx).addCallback( @@ -444,11 +476,18 @@ if self.afterRender is not None: return util.maybeDeferred(self.afterRender,ctx) - if self.buffered: + c = self.hasCache(ctx) + if c is not None: + finishRequest() + return c + + if self.buffered or self.cache: io = StringIO() writer = io.write def finisher(result): - request.write(io.getvalue()) + c = io.getvalue() + self.cacheRendered(ctx, c) + request.write(c) return util.maybeDeferred(finishRequest).addCallback(lambda r: result) else: writer = request.write @@ -532,7 +571,6 @@ else: ## Use the redirectAfterPost url ref = str(redirectAfterPost) - from nevow import url refpath = url.URL.fromString(ref) magicCookie = '%s%s%s' % (now(),request.getClientIP(),random.random()) refpath = refpath.replace('_nevow_carryover_', magicCookie)