如何在WSGI中实现缓存?
我想用Python做一个缓存代理,作为WSGI中间件。我在想,这个中间件怎么才能知道缓存的页面是否过期。根据我的了解,WSGI并不支持类似Java Servlets中的getLastModified(HttpServletRequest req)这个方法。
我不想要的是针对每个用户的缓存策略,比如“自从某个时间后有修改”或者“etag”。我想要的是像代理服务器那样,为所有用户缓存内容。所以缓存需要检查WSGI应用程序或者REST资源是否被修改,从而判断缓存是否过期。
client cache wsgi app
------ ----- --------
| get /some/x | |
|------------------>| /some/x expired? |
| |------------------->|
| | |
| | update /some/x |
| | if modified |
| return /some/x |<-------------------|
|<------------------|
有没有可能在不绕过WSGI的情况下实现这个功能?
3 个回答
0
你可以试试shelve这个东西。这里有个链接可以了解更多。
如果你想用它来缓存网页,可以把网页的代码存到shelve或者缓存里,然后把这些代码返回给用户。当需要修改页面的时候,可以让wsgi来处理。
1
当你提到“构建”时,其实是指自己配置或开发一个工具。现在有很多HTTP缓存工具可以选择。我建议你看看:
使用这些工具,你可以设置超时时间来清除缓存。我想问题在于你的内容有多动态。如果你的内容比较静态,这些工具都应该能满足你的需求。
关于WSGI,这里有一个配置的示例,使用SQUID缓存
3
当然可以。首先,只有你自己知道某个资源是否过期。这个资源可能来自一个文件,或者是数据库中的一篇文章,所以并没有一个通用的方法可以判断“过期与否”。下面是一个简单的例子:
class WSGICache(object):
def __init__(self, app):
self.app = app
self.cache = {}
def is_expired(self, environ):
"""Determine is the resource the request for already expired?
"""
# FIXME: check is the resource expired, by looking
# PATH_INFO, if it is a file, it might be last modified time
# if it is an object from database, see what is the last modified time
return False
def __call__(self, environ, start_response):
path = environ['PATH_INFO']
cached = self.cache.get(path)
# do we have valid cache?
if self.is_expired(environ) or not cached:
cached = list(self.app(environ, start_response))
self.cache[path] = cached
return cached
不过在实际使用中,我建议你使用一些已经构建好的缓存系统,比如Beaker,我觉得它应该能满足你的需求。我没有测试上面的代码,但像这样的中间件应该能够实现你想要的功能。