谷歌应用引擎应用缓存

1 投票
2 回答
556 浏览
提问于 2025-04-17 16:30

在谷歌应用引擎上,我创建了一个自己的用户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)

guestauthorized模块的格式就像你常见的应用脚本,比如:

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()函数的变化。如果你登录了,它不会认出你已经登录,直到所有标签页都关闭。我有两个可能的原因:

  1. isLoggedIn()使用os.environ['HTTP_COOKIE']来获取cookies,看看用户是否登录,然后它会检查cookie数据是否在数据库中有效。可能会出现一个错误,就是服务器端的cookies在页面刷新时没有更新?也许是因为我没有从self.request中获取cookies。

  2. 是否有可能为了节省前端时间,谷歌应用引擎将服务器的脚本缓存到服务器的内存缓存中?我对此表示怀疑,但我对这种行为的原因感到困惑。

提前感谢你的帮助

编辑

经过更多测试,我发现如我所料,router.py文件在添加评论时正确响应并根据用户是否登录进行引导。这似乎表明存在缓存。

编辑 2

我发现了一些关于WSGI应用程序的更多信息:

Python运行环境在单个Web服务器上会在请求之间缓存导入的模块,这类似于独立的Python应用程序即使模块被多个文件导入,也只加载一次模块。由于WSGI处理程序是模块,因此它们在请求之间被缓存。CGI处理程序脚本只有在提供main()例程时才会被缓存;否则,CGI处理程序脚本会在每个请求中加载。

我想知道如何有效地刷新WSGI模块。这无疑会给服务器带来负担,但可以解决我的问题。再次强调,这似乎是一个部分解决方案。

编辑 3

再次尝试在router.py文件中随机化评论是无效的。查找用户登录的id语句完全被忽略,WSGIApplication被设置回原始状态。我还不确定这是由于webapp2模块中的模块缓存,还是由于用户API中的模块缓存。我怀疑是后者。

2 个回答

2

问题不在于“缓存”,而是WSGI应用的工作方式。WSGI进程会持续运行一段时间,并在这段时间内处理多个请求。app是在这个进程启动时定义的,直到进程被更新之前,它是不会改变的。所以在这个时候,你不应该尝试做任何动态的或依赖于请求的事情。

1

把 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 让网页应用可以在不缓存的情况下更改它的目录列表。

撰写回答