龙卷风环境中@cyclone.web.asynchronous的替代

Alternate of @cyclone.web.asynchronous in tornado enviroment

我们现在正在将我们的代码从 cyclone 转移到 tornado。以前我们使用 @cyclone.web.asynchronous 作为我们的 api 之一,用于 cyclone 中的非阻塞异步调用(这样我们就不会阻塞 UI)。在龙卷风中有什么替代方法,@tornado.web.asynchronous 在龙卷风 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()
       
}   

它的tornado等效方法可以是什么

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

使用 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

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

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