在spawn_callback中使用异步进行写入会导致RuntimeError:finish()之后无法进行write()

时间:2019-04-27 15:40:46

标签: tornado

我正在尝试让后台进程每10秒运行一次,以将一些随机内容写入网页。页面加载将一次触发此后台进程。 异步def do_something()在print(message)上有效,但在self.write(message)上失败

我不确定是否应该将@ tornado.gen.coroutine装饰器添加到do_something中,但是尝试了一下并得到引用,说它从未被等待。

"""
Python 3.5
This is the MainHandler being called from the def main()
"""
class MainHandler(tornado.web.RequestHandler):

    def get(self):
        global background_flag

        self.write("Hello, world")
        # Coroutines that loop forever are generally started with spawn_callback()
        if not background_flag:
            print ("Launching spawn_callback ...")
            tornado.ioloop.IOLoop.current().spawn_callback(self.minute_loop)
            background_flag = True

    async def minute_loop(self):
        while True:
            # await self.do_something() #do_something must be an async def as well non-blocking
            await self.do_something()
            await tornado.gen.sleep(10)

    async def do_something(self):
        now = DT.now()
        now_str = now.strftime("%d/%m/%Y %H:%M:%S")
        message = "[{0}] {1} : Running this".format(inspect.stack()[0].function, now_str)
        print (message)
        self.write(message)

我希望网页显示以下消息:
[do_something] 27/04/2019 23:42:08:运行此
[do_something] 27/04/2019 23:42:18:运行此

1 个答案:

答案 0 :(得分:0)

您不需要spawn_callback。只需将get方法转换为异步协程,然后将await转换为minute_loop

async def get(self):
    ...
    await self.minute_loop()

注意:网页不应该是长期运行的连接。如果要使用新数据更新网页,则应考虑使用websocket。