Question

Why incoming request are not being processed while another request is in the "waiting" state?

If you look at the code below, function "get" has a tornado task which is executed with "yield" keyword, which would mean "wait for a callback to be executed". In my code, the callback is never executed. If you run request second time, while first is on hold, the second request is not processed. If you run any other requests, they are being processed just fine.

So, my actions: 1. Start application 2. GET localhost:8080/ - Application is printing output "incoming call" 3. GET localhost:8080/anotherrequest - Application is printing output "another request" 4. GET localhost:8080/ - Application is not printing any output while I'm expecting it to print "incoming call". Why?

So, why this piece of code gets blocking? Code sample is attached.

I was using tornado 2.1 and python 2.7 to run this sample.

Thank you

import tornado
import tornado.web
from tornado import gen

class AnotherHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        print 'another request'
        self.finish()

class MainHandler(tornado.web.RequestHandler):
    def printStuff(*args, **kwargs):
        print 'incoming call'

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        result = yield tornado.gen.Task(self.printStuff); 

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/anotherrequest", AnotherHandler)
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()
Was it helpful?

Solution 2

Found the problem, it's actually happening when requests are made from the browser. With "curl" everything works as expected. Sorry for inconvenience.

OTHER TIPS

Each new request to "localhost:8080/" will, in fact, cause your application to print "incoming call." However, requests to "localhost:8080/" will never finish. In order for the yield statement to be used, printStuff has to accept a callback and execute it. Also, an asynchronous get function must call self.finish:

class MainHandler(tornado.web.RequestHandler):
    def printStuff(self, callback):
        print 'incoming call'
        callback()

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        result = yield tornado.gen.Task(self.printStuff)
        self.finish()

It's easier to use Tornado's modern "coroutine" interface instead of gen.Task and gen.engine:

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def printStuff(self):
        print 'incoming call'

    @gen.coroutine
    def get(self):
        result = yield self.printStuff()
        self.finish()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top