1

I have the following two handlers for a web.py setup:

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)

The app runs on web.py shipped cherrypy (app.run()) or gevent server.

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()

Session works fine in count1 case but not always in count2. In the first time a page of /count2 is loaded the counter is increased once, but refreshing after that doesn't increase the counter in session i.e. the update to session is never saved. What would be wrong here?

Webpy installed from pypi or latest from github behaves the same in this case.

After digging into the code, the actual reason seems to be that, when the handler using yield, it is only being called to return the generator object, and then are returned from all enclosing processors (e.g. Session._processor which calls _save in the finally block). Web.py makes sure that the generator is completely unrolled before returning the data to the client, but the unroll process is after all processors which is completely different behavior comparing to normal function handlers.

So the question is as: is there any fixes, or workarounds (apart from calling Session._save manually) to this?

Thanks in advance for any answers!

Ryan
  • 870
  • 1
  • 7
  • 18

1 Answers1

0

Maybe it happens because yield returns a generator and not a value.

Refs:

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

What does the "yield" keyword do in Python?

Community
  • 1
  • 1
tschertel
  • 26
  • 1
  • Hi, thanks for the information. I'm aware of the different behavior of generators and was specifically choosing to use yield (with gevent) for some long polling scenarios. The only question is that, seems the webpy has inconsistence behaviors for generators and functions, are there any workarounds for the problem? Thanks! – Ryan Jun 16 '13 at 05:39
  • Ryan, I'll ask this on web.py's mail list. Maybe Anand, who is maintaining web.py now can help you. – tschertel Jun 21 '13 at 03:49
  • Actually, why don't you join web.py's mail list? Community is very receptive and web.py is going to change a lot in next releases. Maybe you could help. – tschertel Jun 21 '13 at 17:13