简体   繁体   English

为什么龙卷风中的异步功能会阻塞?

[英]Why asynchronous function in tornado is blocking?

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". 如果你看下面的代码,函数“get”有一个龙卷风任务,用“yield”关键字执行,这意味着“等待回调被执行”。 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". 所以,我的行动:1。启动应用程序2. GET localhost:8080 / - 应用程序打印输出“来电”3. GET localhost:8080 / anotherrequest - 应用程序打印输出“另一个请求”4. GET localhost:8080 / - 应用程序不打印任何输出,而我期望它打印“来电”。 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. 我使用龙卷风2.1和python 2.7来运行此示例。

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

Each new request to "localhost:8080/" will, in fact, cause your application to print "incoming call." 事实上,对“localhost:8080 /”的每个新请求都会导致您的应用程序打印“来电”。 However, requests to "localhost:8080/" will never finish . 但是,对“localhost:8080 /”的请求永远不会完成 In order for the yield statement to be used, printStuff has to accept a callback and execute it. 为了使用yield语句, printStuff必须接受回调并执行它。 Also, an asynchronous get function must call self.finish : 另外,异步get函数必须调用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: 使用Tornado的现代“coroutine”界面而不是gen.Task和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()

Found the problem, it's actually happening when requests are made from the browser. 发现问题,它实际上是在从浏览器发出请求时发生的。 With "curl" everything works as expected. 随着“卷曲”,一切都按预期工作。 Sorry for inconvenience. 对造成的不便表示歉意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM