web.py セットアップ用に次の 2 つのハンドラーがあります。
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 のページが最初に読み込まれると、カウンターは 1 回増加しますが、その後更新してもセッションのカウンターは増加しません。つまり、セッションへの更新は保存されません。ここで何が間違っているでしょうか?
この場合、pypi からインストールされた Webpy または github から最新の Webpy は同じように動作します。
コードを掘り下げた後、実際の理由は、ハンドラーがyieldを使用している場合、ジェネレーターオブジェクトを返すためにのみ呼び出され、その後、すべての囲んでいるプロセッサーから返されるためです(たとえば、finallyで_saveを呼び出すSession._processor)ブロック)。Web.py は、データをクライアントに返す前にジェネレーターが完全にアンロールされていることを確認しますが、アンロール プロセスはすべてのプロセッサの後であり、通常の関数ハンドラーとはまったく異なる動作です。
したがって、質問は次のとおりです:これに対する修正または回避策(Session._saveを手動で呼び出す以外)はありますか?
ご回答ありがとうございます。