Beaker already has methods for invalidating:

Below is what I use (I have defined regions, but should be similar without them):

@cache.region('user', 'user_profile')
def get_profile_user(uid):
    # get user from database
    return user

def flush_profile_user_cache(uid):
    cache.region_invalidate(get_profile_user, 'user', 'user_profile', uid)

Basically, just call the flush method when you need to invalidate the cache.
Dwipal

writeson wrote:
Hi all,

I'm Doug, the original poster of this thread. I'm including some code
examples of what I'm doing currently to try and manage finely grained
cache invalidation.

Here is some code I've written in my controller, this uses the normal
@beaker_cache decorator to cache a method call. Right below it is a
new decorator, @beaker_cache_invalidate which is my attempt to provide
a way to invalidate a particular method call/parameter signature
cache:


     @beaker_cache(expire=300, cache_response=False,
invalidate_on_startup=True)
     def _getOrder(self, order_number):
         return self.model.order.getOrder(order_number)

     @beaker_cache_invalidate()
     def _getOrderInvalidate(self, order_number):
         return self.model.order.getOrder(order_number)

In my controller I call self._getOrder(some_order_number) to get order
data and the decorate caches the data returned based on the method
name and parameters passed. At some later time the order data get
changed as the result of a user action (form save), then I call
self._getOrderInvalidate(some_order_number) to invalidate the
particular cache so the next call to self._getOrder(some_order_number)
will get fresh data from the database rather than the cache.

Here is the code for the @beaker_cache_invalidate:


def beaker_cache_invalidate(key="cache_default"):
     '''This function decorator will invalidate a method/function that
has been
     decorated with the @beaker_cache decorator. This will cause the
underlying
     cached method/function (minus the "Invalidate" part of the name)
     to be called again. The function being decorated should be called
with
     the same "signature" as the original cached version'''
     def _beaker_cache_invalidate(func):
         def __beaker_cache_invalidate(*args, **kwargs):
             pylons = get_pylons(args)
             # is the cache enabled?
             enabled = pylons.config.get("cache_enabled", "True")
             if asbool(enabled):
                 if key:
                     key_dict = kwargs.copy()
                     key_dict.update(_make_dict_from_args(func, args))

                     if key != "cache_default":
                         if isinstance(key, list):
                             key_dict = dict((k, key_dict[k]) for k in
key)
                         else:
                             key_dict = {key: key_dict[key]}
                 else:
                     key_dict = None
                 self = None
                 if args:
                     self = args[0]
                 namespace, cache_key = create_cache_key(func,
key_dict, self)
                 # adjust the cache_key match the real cached function
we want to invalidate
                 cache_key = cache_key.replace("Invalidate", "")
                 cache.get_cache(namespace).remove(cache_key)
         return __beaker_cache_invalidate
     return _beaker_cache_invalidate


def _make_dict_from_args(func, args):
     """Inspects function for name of args"""
     args_keys = {}
     for i, arg in enumerate(inspect.getargspec(func)[0]):
         if arg != "self":
             args_keys[arg] = args[i]
     return args_keys

The decorator removes the "Invalidate" part of the name (which means
all my Invalidator functions have to have this format) and then trys
to build a cache_key that matches the original function call,
including parameters, to invalidate the cache.

I'm not sure at all if this is a good approach, or even very elegant.
Any tips, pointers, comments would be greatly appreciated.

Thanks,
Doug


--
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to