0

我们现在正在将我们的代码从旋风转移到龙卷风。以前我们使用@cyclone.web.asynchronous 作为我们的 api 之一,用于在 cyclone 中进行非阻塞异步调用(这样我们就不会阻塞 UI)。在 tornado 中有什么替代方法,@tornado.web.asynchronous 在 tornado 6.1 中不起作用。我的旋风代码是这样的

class ABCHandler(cyclone.web.RequestHandler):

    @cyclone.web.asynchronous
    def post(self):
    some_validation()
    # Spawn a thread to import the files and leave the post method
    # asynchronous decorator will keep the request open to write the response on, 
    #  once the import is complete
    file_handler.start()  ---- this is a thread that do all the heavy work and in this method we are 
                               closing the request with self.finish

Class file_handler():
     run(self):
         {
          ---do some heavy work, like importing a file
          self.importing_a_large_file()
          self.set_status(status)
          self.write(json_response)
          self.finish()
       
}   

它的龙卷风等效方法是什么。

我尝试了各种方法,例如添加 gencouroutine 装饰器,将方法名称更改为异步,但似乎没有任何效果。

4

2 回答 2

0

听起来cyclone.web.asynchronous等同于tornado.web.asynchronous,因此您最好先从 cyclone 迁移到 Tornado 5.1(其中asynchronous仍然支持装饰器),然后在单独的步骤中迁移到协程和 Tornado 6.x。(或者如果 cyclone 支持协程,则在切换到 Tornado 之前先转到 cyclone 上的协程)。

如果您尝试cyclone.web.asynchronous一次性使用原生协程从 Tornado 6 迁移到 Tornado 6,这将是一次非常困难的重构。此外,您的示例代码看起来像是RequestHandler.finish从另一个线程调用方法。我不确定旋风是否允许这样做,但绝对不是龙卷风。

于 2021-01-18T15:02:29.177 回答
0

使用 Python 的async def协程。

您不能在 Tornado 中使用常规线程,因此您必须使用该run_in_executor方法。它将在单独的线程中运行代码,但允许您在不阻塞的情况下等待结果。

class ABCHandler(tornado.web.RequestHandler):
    async def post(self):
        loop = tornado.ioloop.IOLoop.current()

        some_data = await loop.run_in_executor(executor=None, func=blocking_func)

       self.write(some_data)


# this is a blocking code
# you don't have to create a separate thread for this
# because `run_in_executor` will take care of that.
def blocking_func():
    # do blocking things here
    return some_data
于 2021-01-18T11:44:32.640 回答