[Checkins] SVN: lovely.viewcache/trunk/src/lovely/viewcache/ Provide a `cacheHit` method which is called if a cached result is used.

Jürgen Kartnaller juergen at kartnaller.at
Sat Feb 10 14:17:31 EST 2007


Log message for revision 72497:
  Provide a `cacheHit` method which is called if a cached result is used.
  
  This can be used for code which is required even if the cached result is used.
  Example :
   If your view needs a resource using "zc.resourcelibrary.need" you do this here.
  
  

Changed:
  U   lovely.viewcache/trunk/src/lovely/viewcache/README.txt
  U   lovely.viewcache/trunk/src/lovely/viewcache/interfaces.py
  U   lovely.viewcache/trunk/src/lovely/viewcache/view.py

-=-
Modified: lovely.viewcache/trunk/src/lovely/viewcache/README.txt
===================================================================
--- lovely.viewcache/trunk/src/lovely/viewcache/README.txt	2007-02-10 17:09:27 UTC (rev 72496)
+++ lovely.viewcache/trunk/src/lovely/viewcache/README.txt	2007-02-10 19:17:30 UTC (rev 72497)
@@ -25,6 +25,7 @@
   ...     interface.implements(IContent)
   ...     def __init__(self, name):
   ...         self.count = 0
+  ...         self.cacheHits = 0
   ...         self.name = name
   >>> content = Content(u'content 1')
   >>> root[u'content'] = content
@@ -42,6 +43,8 @@
   >>> from zope.publisher.interfaces.browser import IBrowserView
   >>> from zope.publisher.browser import BrowserView
   >>> class View(BrowserView):
+  ...     def cacheHit(self):
+  ...         self.context.cacheHits += 1
   ...     def __call__(self, *args, **kwargs):
   ...         self.context.count += 1
   ...         return u'"%s" is rendered %s time(s)'% (
@@ -84,12 +87,24 @@
   >>> view()
   u'"content 1" is rendered 1 time(s)'
 
+Our view call implements the uncachedCall method and increments `cacheHits` on
+its contexts every time it is called. This special method is called by the
+cached view any time a value from the cache is returned.
+
+  >>> content.cacheHits
+  0
+
 Rendering the view again will return the same result because the cached result
 is used.
 
   >>> view()
   u'"content 1" is rendered 1 time(s)'
 
+And our hit counter counts up.
+
+  >>> content.cacheHits
+  1
+
 The cachingOn property allows the control of the caching of the view. If
 cachingOn returns False the view is not cached.
 
@@ -200,7 +215,7 @@
 Cached Viewlets
 ---------------
 
-Caching for viewlets can be used the same as cached views are used.
+Caching for viewlets can be used the same way as cached views are used.
 
   >>> from lovely.viewcache.view import cachedViewlet
 
@@ -217,6 +232,8 @@
 
   >>> from zope.viewlet.viewlet import ViewletBase
   >>> class Viewlet(ViewletBase):
+  ...     def cacheHit(self):
+  ...         self.context.cacheHits += 1
   ...     def update(self):
   ...         self.context.count += 1
   ...     def render(self):
@@ -237,12 +254,17 @@
   >>> viewlet.render()
   u'viewlet for context "content 3" is rendered 1 time(s)'
 
+Our viewlet implements the cacheHit method and increments `cacheHits` on
+its contexts every time it is called. This special method is called by the
+cached viewlet any time a value from the cache is returned.
+
+  >>> content3.cacheHits
+  0
+
 Because the viewlet is now cached update is not called again. Because the
 update method increments the count in the context we check for a change on the
 count.
 
-  >>> content3.count
-  1
   >>> viewlet.update()
   >>> content3.count
   1
@@ -252,6 +274,9 @@
   >>> viewlet.render()
   u'viewlet for context "content 3" is rendered 1 time(s)'
 
+  >>> content3.cacheHits
+  1
+
   >>> cache.invalidate(dependencies=['viewlet'])
   >>> viewlet.update()
   >>> viewlet.render()

Modified: lovely.viewcache/trunk/src/lovely/viewcache/interfaces.py
===================================================================
--- lovely.viewcache/trunk/src/lovely/viewcache/interfaces.py	2007-02-10 17:09:27 UTC (rev 72496)
+++ lovely.viewcache/trunk/src/lovely/viewcache/interfaces.py	2007-02-10 19:17:30 UTC (rev 72497)
@@ -25,12 +25,8 @@
 from lovely.viewcache.i18n import _
 
 
-class ICachedViewletManager(ILocation):
-    """A viewlet manager wich caches the results returned from his viewlets"""
-
-
 class ICacheableView(ILocation):
-    """A marker to make a viewlet cacheable"""
+    """A view implements this interface if it is turned into a cachable view"""
 
     cachingKey = schema.TextLine(
             title = u'Cache key',
@@ -63,7 +59,26 @@
                 at runtime.
             """)
 
+    def cacheHit(self, *args, **kwargs):
+        """Called from __call__ if the result is taken from the cache
 
+        This gives a view a hook to do things which must be done even if the
+        cached value is used.
+        Example :
+            If your view needs a resource using "zc.resourcelibrary" you do
+            this here.
+        IMPORTANT :
+            it is not called if the regular __call__ of the view is used to
+            get the result.
+        """
+
+
+class ICacheableViewlet(ICacheableView):
+    """A viewlet implements this interface if it is turned into a cachable
+       viewlet
+    """
+
+
 class IViewCache(IRAMCache):
     """A special cache used for the view cache."""
 

Modified: lovely.viewcache/trunk/src/lovely/viewcache/view.py
===================================================================
--- lovely.viewcache/trunk/src/lovely/viewcache/view.py	2007-02-10 17:09:27 UTC (rev 72496)
+++ lovely.viewcache/trunk/src/lovely/viewcache/view.py	2007-02-10 19:17:30 UTC (rev 72497)
@@ -23,11 +23,13 @@
 from zope.publisher.browser import BrowserView
 from zope.traversing.browser.absoluteurl import absoluteURL
 
-from lovely.viewcache.interfaces import IViewCache, ICacheableView
+from lovely.viewcache.interfaces import (IViewCache,
+                                         ICacheableView,
+                                         ICacheableViewlet,
+                                        )
 
 
 class CacheMixinBase(object):
-    interface.implements(ICacheableView)
 
     _cachingOn = True
     __cachedValue__ = None
@@ -94,9 +96,16 @@
 
 
 class CachedViewMixin(CacheMixinBase):
+    interface.implements(ICacheableView)
 
     def __call__(self, *args, **kwargs):
-        if not self._getCachedResult():
+        if self._getCachedResult():
+            c = getattr(super(CachedViewMixin, self),
+                        'cacheHit',
+                        None)
+            if c:
+                c(*args, **kwargs)
+        else:
             result = super(CacheMixinBase, self).__call__(*args, **kwargs)
             self._setCachedResult(result)
         return self.__cachedValue__
@@ -117,6 +126,7 @@
 
 
 class CachedViewletMixin(CacheMixinBase):
+    interface.implements(ICacheableViewlet)
 
     def update(self):
         if not self._getCachedResult():
@@ -127,6 +137,12 @@
             if not self._getCachedResult():
                 result = super(CachedViewletMixin, self).render()
                 self._setCachedResult(result)
+        else:
+            c = getattr(super(CachedViewletMixin, self),
+                        'cacheHit',
+                        None)
+            if c:
+                c()
         return self.__cachedValue__
 
 



More information about the Checkins mailing list