[Zope-CVS] CVS: Products/PluggableAuthService/doc - caching.stx:1.1.2.1

Jens Vagelpohl jens at dataflake.org
Tue Oct 26 10:20:50 EDT 2004


Update of /cvs-repository/Products/PluggableAuthService/doc
In directory cvs.zope.org:/tmp/cvs-serv24678/doc

Added Files:
      Tag: jens-implement_caching_branch
	caching.stx 
Log Message:
- checkpoint checkin


=== Added File Products/PluggableAuthService/doc/caching.stx ===
Caching

  The PluggableAuthService contains a caching mechanism based on the built-in
  Zope Caching framework with a mix-in class that defines caching methods for
  cacheable content and so-called Cache Managers that store cacheable data.


  How does the site admin use it?

    Given a plugin that is cache-enabled the steps to using the cache are
    easy. The site administrator needs to...

    o Instantiate a "PAS RAM Cache Manager" inside the PluggableAuthService

    o Using the "Cache" tab in the cache-enabled plugin's ZMI view,
      associate the plugin with the PAS RAM Cache Manager

    At this point values will be cached inside the PAS RAM Cache Manager. The
    effect can be viewed easily on the "Statistics" tab in the Cache Manager
    ZMI view, which shows which plugins have stored values, how many values
    are stored, an approximation of the memory consumption for the cached
    data, and how often the data has been retrieved from cache.

    The Statistics view also provides an easy way to summarily invalidate 
    cached values if needed. However, cache invalidation should be handled
    by the plugins itself if it is possible.


  How does a plugin programmer use it?

    Due to the pluggable (and thus infinitely variable) nature of the 
    PluggableAuthService it is up to the plugin developer to decide what to
    cache and how to do so. Some of the built-in plugins provide a sample
    implementation by caching certain methods' return values and invalidating
    these records where necessary. In a nutshell, these are the steps needed
    to enable cacheability at the plugin level:

    o Add the PASCacheable mix-in class to the list of classes your plugin
      subclasses from

    o Determine which method calls should have their return values cached, 
      and which method calls affect the return value of the method that is
      being cached and thus should invalidate the cache

    o In the cached method, add code to try and look up the return value in
      the cache first, and only perform the computation if the cache does
      not have the desired data. At the end of computing the return value,
      add it to the cache

    o Add cache invalidation to those methods deemed to affect the cached
      method's return value.

    A little illustration using code snippets::

      from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
      from Products.PluggableAuthService.PASCache import PASCacheable
      from Products.PluggableAuthService.utils import createViewName

      class MyPlugin(BasePlugin, PASCacheable):

          def retrieveData(self, key):
              """ Get data for the given key """
              view_name = createViewName('retrieveData', key)
              keywords = {'key': key}
              cached_info = self.ZCacheable_get( view_name=view_name
                                               , keywords=keywords
                                               , default=None
                                               )

              if cached_info is not None:
                  return cached_info

              return_value = <perform return value calculation here>

              # Put the computed value into the cache
              self.ZCacheable_set( return_value
                                 , view_name=view_name
                                 , keywords=keywords
                                 )

              return return_value

          def change_data(self, key, new_value):
              """ Change the value for the given key """
              <perform changes here>

              # Also, remove from the cache
              view_name = createViewName('retrieveData', key)
              self.ZCacheable_invalidate(view_name=view_name)

    As you can see, due to the variable nature of plugins certain items,
    such as the relationships between the different accessor and mutator
    methods in use, cannot be computed or guessed, they have to be hardcoded.
    That's why inside change_data the view_name "retrieveData" is hardcoded
    as the caching key for information returned from the retrieveData method.

    This example also shows how, due to the way the built-in Zope caching
    framework handles cached data, it is not possible to invalidate specific
    entries, such as the value for one specific view_name/key combination. 
    All cached records for a specific view_name are invalidated at once.

    It must be kept in mind that it is very hard if not impossible to reach
    a state where the cache is 100% synchronized with the live data in
    those situations where information is retrieved and manipulated in more
    than one plugin. Imagine a situation where one plugin's cached answer
    is dependent on another plugin that handles updating the underlying data.
    The retrieving plugin is not notified of updates happening in the 
    "mutator plugin" (and thus does not invalidate cached data) unless the 
    plugin developer forces some nasty cross-plugin dependencies.




More information about the Zope-CVS mailing list