Created
October 10, 2012 21:16
-
-
Save oubiwann/3868462 to your computer and use it in GitHub Desktop.
Memcache, Twisted Templates, and the Klein Mirco-webframework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
A simple configuration file. | |
""" | |
cache = True | |
debug = True |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import functools | |
import config, helper | |
def cache(routeFunction): | |
""" | |
A decorator for caching pages. | |
""" | |
@functools.wraps(routeFunction) | |
def wrapper(request): | |
""" | |
This wrapper needs to return something that klein knows how to render, | |
such as Twisted templates (page classes) or something that is | |
"flattenable" by Twisted template code (such as tags or strings). | |
""" | |
pageClass = routeFunction(request) | |
if not config.cache: | |
return pageClass() | |
return helper.MemCacheHelper(request, pageClass).getPage() | |
return wrapper |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from twisted.internet import protocol, reactor | |
from twisted.protocols import memcache | |
from twisted.python import log | |
from twisted.web.template import flattenString | |
import config | |
class MemCacheHelper(object): | |
""" | |
""" | |
def __init__(self, request, pageClass): | |
self.request = request | |
self.pageClass = pageClass | |
self.memcache = None | |
self.key = "" | |
def setPage(self, page): | |
d = self.memcache.set(self.key, page) | |
d.addErrback(log.msg) | |
return page | |
def getOrFlattenPage(self, result): | |
flags, page = result | |
if page: | |
if config.debug: | |
log.msg("Cache hit; skipping page generation ...") | |
return page | |
if config.debug: | |
log.msg("No page in cache; getting and setting ...") | |
d = flattenString(self.request, self.pageClass()) | |
d.addErrback(log.msg) | |
d.addCallback(self.setPage) | |
return d | |
def pokeMemCache(self, mem): | |
if not mem: | |
if config.debug: | |
log.msg("Cannot connect to memcache server!") | |
return self.pageClass() | |
self.memcache = mem | |
d = self.memcache.get(self.key) | |
d.addErrback(log.msg) | |
d.addCallback(self.getOrFlattenPage) | |
return d | |
def getPage(self): | |
""" | |
""" | |
# The key should uniquely identify renderable content, e.g., if you | |
# have a page that can only be rendered one way, then the URL should be | |
# fine. However, if that page will render differently per logged in | |
# user, for example, then you'd want to add a user id to the key as | |
# well. See the following for more information: | |
# | |
# * http://code.google.com/p/memcached/wiki/NewProgramming#Key_Usage | |
# * http://code.google.com/p/memcached/wiki/NewProgrammingTricks#Reducing_key_size | |
self.key = self.request.path | |
if config.debug: | |
log.msg("Generated key:", self.key) | |
client = protocol.ClientCreator(reactor, memcache.MemCacheProtocol) | |
d = client.connectTCP("localhost", memcache.DEFAULT_PORT) | |
d.addErrback(log.msg) | |
d.addCallback(self.pokeMemCache) | |
d.addErrback(log.msg) | |
return d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from twisted.web.template import Element | |
class BasePage(Element): | |
""" | |
Silly pase page. | |
""" | |
content = "" | |
def __init__(self): | |
Element.__init__(self, loader=self.content) | |
class TonsOfWorkPage(Element): | |
""" | |
Okay, so maybe not *tons* of work... | |
""" | |
content = "0100110100" * 1024 | |
class LazyDoNothingPage(Element): | |
""" | |
This guy's sitting outside his dorm in boxes and flip-flops. | |
""" | |
content = "Man, whatever. I'm just gonna chill." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import klein | |
import pages | |
@klein.route("/expensive-page") | |
@pages.cache | |
def notcheap(request): | |
return pages.TonsOWorkPage | |
@klein.route("/lazy-page") | |
def cheap(request): | |
return pages.LazyDoNothingPage() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment