Powerful in-house caching system is enabled

PoweredSites' in-house caching system has been enabled, generally, the performance is boosted over 50 times in the server side.For example, it will only take 2ms to render the homepage from cache if cache is enabled and is not expired, or it need do more database queries and templates rendering, so it will take about 170ms.

The caching system can be used to cache

  1. A whole web page
  2. An UIModule
  3. A normal functional in handler or UIModule.

There are three cache decorators:

  1. cache.page, cache a whole web page to MonogoDB. It is just used to decorate SUPPORTED_METHODS (eg. get and post) in a handler.
  2. cache.cache, cache a functional or UIModule(render functional in a UIModule) to MonogoDB.
  3. cache.mem, cache a functional or UIModule to Python dict in memory. It just be used for caching some data which are seldom changed but the data are used frequently.

How to use them, let's see the cache arguments at first.

def cache(expire=7200, condition="", key="", anonymous=False):
    """Decorator which caches the value of a method in a handler or a module.

    expire: Cache will be expired time from now in seconds.
    condition: If the result of sql condition has changed, then cache expired. 
    key: The unique key of the cache identify in the DB, it will auto generate 
         one if it not be set

    cache_pre: A method which is defined in self(handler or module), 
                it always be executed before cache or get from cache.

    cache_condition: A property which is defined in self(handler or module), it
                is used to construct a complex condition.
    """
    def wrapper(func, self, *args, **kwargs):
        # caching

Then let's show the power in some examples:

  • cache a whole page

    class IndexHandler(BaseHandler):
        @cache.page(expire=3600)
        def get(self):                
            self.render("index.html")
    
  • just cache for anonymous user

    class IndexHandler(BaseHandler):
        @cache.page(anonymous=True)
        def get(self):                
            self.render("index.html")
    
  • cache a functional

    class IndexHandler(BaseHandler):
        @cache.cache()
        def do_complex_query(self):
            # do time cosuming queries and return the values
            self.db.query("complex query 1")
            self.db.query("complex query 2")           
            return "query resluts"
    
  • cache an ui_module

    class IndexModule(UIModule):
        @cache.cache()
        def render(self):
            self.render_string("index_module.html")
    
  • cache to memory

    class TomemModule(UIModule):
        @cache.mem()
        def render(self):
            self.render_string("tomem_module.html")
    
  • cache with condition checking

    class IndexHandler(BaseHandler):
        # The cache will expired immediately if the count(*) has changed, 
        # for example a new blog is posted, so the cache is very dynamic.
        @cache.page(condition="select count(*) from entries")
        def get(self):               
            self.render("index.html")
    
  • cache with a complex condition and do some cache_pre operations

    class IndexHandler(BaseHandler):
        @property
        def cache_condition(self):
            # It will try to use this property as cache condition if no condition
            # argument. You can construct a complex condition here as your wish.
            return str("select updated from entry where id = %s" % self.entry_id)
    
        def cache_pre(self, entry_id):
            # It always will be executed before `get` or `post` and cache_condition, 
            # it has the same arguments as `get` or `post`.
            # You can do something here before try to get the cache.
    
            self.entry_id = entry_id
    
            # Do cache_pre operations
            # eg. update the click count of this entry
    
        @cache.page()
        def get(self, entry_id):            
            self.render("entry.html")
    

Please refer to the source code for more detail information.

Felinx Lee   August 6, 2010
Comments blog comments powered by Disqus