【问题标题】:Does web.py session / processor work when yield is used in handlers?当在处理程序中使用 yield 时,web.py 会话/处理器是否工作?
【发布时间】:2013-06-15 11:09:16
【问题描述】:

我有以下两个用于 web.py 设置的处理程序:

class count1:
    def GET(self):
        s.session.count += 1
        return str(s.session.count)

class count2:
    def GET(self):
        s.session.count += 1
        yield str(s.session.count)

应用运行在 web.py 自带的 cherrypy (app.run()) 或 gevent 服务器上。

urls = (
    "/count1", "count.count1",
    "/count2", "count.count2",
)

session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'count': 0})
s.session = session
app = web.application(urls, locals())

print "Main: setting count to 1"    

from gevent.wsgi import WSGIServer
if __name__ == "__main__":
    usecherrypy = False
    if usecherrypy:
        app.run()
    else: # gevent wsgiserver
        wsgifunc = app.wsgifunc()
        server = WSGIServer(('0.0.0.0', 8080), wsgifunc, log=None)
        server.serve_forever()

会话在 count1 情况下工作正常,但在 count2 情况下并非总是如此。在第一次加载 /count2 的页面时,计数器会增加一次,但之后刷新不会增加会话中的计数器,即永远不会保存对会话的更新。这里有什么问题?

从 pypi 安装的 Webpy 或从 github 安装的最新 Webpy 在这种情况下表现相同。

深入研究代码,实际原因似乎是,当处理程序使用yield时,它只是被调用返回生成器对象,然后从所有封闭处理器返回(例如Session._processor调用_save在 finally 块中)。 Web.py 确保生成器在将数据返回给客户端之前完全展开,但展开过程毕竟是处理器,与普通函数处理程序相比,这是完全不同的行为。

所以问题是:对此是否有任何修复或解决方法(除了手动调用 Session._save)?

提前感谢您的任何回答!

【问题讨论】:

    标签: python web.py


    【解决方案1】:

    可能是因为 yield 返回的是生成器而不是值。

    参考:

    http://od-eon.com/blogs/calvin/python-yield-versus-return/

    What does the "yield" keyword do in Python?

    【讨论】:

    • 您好,感谢您提供的信息。我知道生成器的不同行为,并且特别选择在一些长轮询场景中使用 yield(与 gevent)。唯一的问题是,似乎 webpy 对生成器和函数有不一致的行为,是否有解决该问题的方法?谢谢!
    • Ryan,我会在 web.py 的邮件列表中问这个问题。也许现在维护 web.py 的 Anand 可以帮助你。
    • 其实你为什么不加入web.py的邮件列表呢?社区非常乐于接受,并且 web.py 将在下一个版本中发生很大变化。也许你可以帮忙。
    猜你喜欢
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多