Where is the best place to put caching logic in an AppEngine?
I wrote an app for Google AppEngine and I would like to use the memcache API to reduce CPU time per request. I profiled the application and found that most of the cpu time is in the rendering of the template and the API calls in the datastore, and after talking with a colleague I jumped (maybe a little earlier?) To the conclusion that caching a snippet of a HTML-rendered page would cut significantly CPU time per request. The caching pattern is pretty clean, but the question of where to put this caching and eviction logic is a bit of a mystery to me.
For example, imagine that the main page of an application contains an "Announcements" section. This section will need to be redisplayed after:
- first read for everyone in the account,
- added a new ad and
- removed old ad
Some options for calling the method evict_announcements_section_from_cache()
:
- in declaration methods
.delete()
and.put()
- in the RequestHandler method
.post()
- somewhere else?
Then, on the RequestHandler request page, I can potentially call get_announcements_section()
that will follow the standard memcache templates (check cache, add to cache on skip, return value) and pass that HTML to the template for that page snippet.
Is it a typical design pattern to put your caching logic in the model or controller / RequestHandler or somewhere else? Ideally, I would like to avoid tentacle preemptive logic all over the code.
source to share
I have a decorator like this in an open source Github project:
http://github.com/jamslevy/gae_memoize/tree/master
It's a little deeper, allowing for things like forcing a function (when you want to refresh the cache) or forcing caching locally ... these were the things I needed in my application, so I baked them into my memorable decorator.
source to share
Several alternatives to regular check-out:
- The obvious one: don't evict or set a timer. Even a very short one - a few seconds - can cut the effort for a huge amount of popular application, without users even noticing that the data can become out of date in a few seconds.
- Instead of an eviction, generate a cache key based on criteria that change when the data is executed. For example, if it's cheap to extract a key from the latest ad, you can use it as part of the cached data key. When you publish a new ad, you are looking for a key that does not exist and create a new one as a result.
source to share