谷歌应用引擎应用缓存
在谷歌应用引擎上,我创建了一个自己的用户API,叫做user,这样就不会和谷歌应用引擎的用户API冲突。就像大多数多用户网站一样,用户在登录与未登录时会看到两个“版本”的网站。因此,我创建了一个叫router.py的文件,里面有以下代码:
import webapp2
from lib import user
import guest
import authorized
if user.isLoggedIn():
app = webapp2.WSGIApplication(authorized.WSGIHandler,debug=True)
else:
app = webapp2.WSGIApplication(guest.WSGIHandler,debug=True)
guest
和authorized
模块的格式就像你常见的应用脚本,比如:
import webapp2
import os
class MainPage(webapp2.RequestHandler):
def get(self,_random):
self.response.out.write('authorized: '+_random)
WSGIHandler = [('/(.*)', MainPage)]
这样,路由文件可以轻松选择使用哪个WSGIApplication的URL目录,通过从guest或authorized模块中获取WSGIHandler变量。不过,用户必须关闭所有标签页,路由器才能检测到isLoggedIn()
函数的变化。如果你登录了,它不会认出你已经登录,直到所有标签页都关闭。我有两个可能的原因:
isLoggedIn()
使用os.environ['HTTP_COOKIE']来获取cookies,看看用户是否登录,然后它会检查cookie数据是否在数据库中有效。可能会出现一个错误,就是服务器端的cookies在页面刷新时没有更新?也许是因为我没有从self.request
中获取cookies。是否有可能为了节省前端时间,谷歌应用引擎将服务器的脚本缓存到服务器的内存缓存中?我对此表示怀疑,但我对这种行为的原因感到困惑。
提前感谢你的帮助
编辑
经过更多测试,我发现如我所料,router.py文件在添加评论时正确响应并根据用户是否登录进行引导。这似乎表明存在缓存。
编辑 2
我发现了一些关于WSGI应用程序的更多信息:
Python运行环境在单个Web服务器上会在请求之间缓存导入的模块,这类似于独立的Python应用程序即使模块被多个文件导入,也只加载一次模块。由于WSGI处理程序是模块,因此它们在请求之间被缓存。CGI处理程序脚本只有在提供main()例程时才会被缓存;否则,CGI处理程序脚本会在每个请求中加载。
我想知道如何有效地刷新WSGI模块。这无疑会给服务器带来负担,但可以解决我的问题。再次强调,这似乎是一个部分解决方案。
编辑 3
再次尝试在router.py文件中随机化评论是无效的。查找用户登录的id语句完全被忽略,WSGIApplication被设置回原始状态。我还不确定这是由于webapp2模块中的模块缓存,还是由于用户API中的模块缓存。我怀疑是后者。
2 个回答
问题不在于“缓存”,而是WSGI应用的工作方式。WSGI进程会持续运行一段时间,并在这段时间内处理多个请求。app
是在这个进程启动时定义的,直到进程被更新之前,它是不会改变的。所以在这个时候,你不应该尝试做任何动态的或依赖于请求的事情。
把 router.py 替换成:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from lib import user
import guest
import authorized
def main():
if user.isLoggedIn():
run_wsgi_app(authorized.application)
else:
run_wsgi_app(guest.application)
if __name__ == "__main__":
main()
把网页应用降级到旧版本后,你可以动态地更改 wsgi 应用程序。这已经测试过了,效果很好!CGI 适配器 run_wsgi_app
让网页应用可以在不缓存的情况下更改它的目录列表。