[英]Python tornado autoreload not working when configured in a module
我试图弄清楚为什么 Python Tornado 自动重载功能在模块内部配置和启动时不起作用。 以下模块包含一个MyTornadoApp
class,如果设置了正确的选项,它会配置并启动 autoreload:
import os
import tornado.autoreload
import tornado.web
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello from index handler!")
class MyTornadoApp:
"""Setup my custom tornado app with default settings"""
# default tornado settings
default_settings = dict(
debug=False,
autoreload=True,
compress_response=True,
port=8080,
)
default_handlers = [
(r"/", IndexHandler),
]
def __init__(self, user_settings):
self.options = {**self.default_settings, **user_settings}
if self.options['autoreload'] == True:
self._autoreload_config()
self.tornado = tornado.web.Application(self.default_handlers,
**self.options)
def _autoreload_config(self):
"""Setup autoreload for tornado"""
print("Setting up autoreload for tornado...")
# autoreload (exclusive) monitor file
monitoring_file = os.path.abspath('autoreload')
if not os.path.isfile(monitoring_file):
with open(monitoring_file, 'w', encoding='UTF-8') as f:
f.write('Do NOT delete. Monitoring changes in this file!')
tornado.autoreload.watch(monitoring_file)
tornado.autoreload.start()
下面的主要 python 脚本随后创建了 tornado 应用程序,但不幸的是,只有在调用start
时autoreload
才有效(同样,根据 Tornado 发出的警告消息)。 任何ideias为什么会这样? 它是功能还是错误? 我错过了什么? TIA。
import asyncio
import tornado.web
from tornadoapp import MyTornadoApp
async def main():
################################################################
# Why do I need this in order to autoreload work properly???
################################################################
if app.options['autoreload'] == True:
tornado.autoreload.start()
app.tornado.listen(app.options['port'])
print(f"Tornado is listening on port {app.options['port']}")
await asyncio.Event().wait()
if __name__ == "__main__":
my_settings = dict(
debug=False,
autoreload=True,
)
app = MyTornadoApp(my_settings)
asyncio.run(main())
请注意警告信息: tornado.autoreload started more than once in the same process
。 但是,如果我们从main()
function 中删除tornado.autoreload.start()
行,那么如果我们更改监控文件(或任何其他监视文件),将不会触发自动重载。
这是asyncio.run
的一个不幸的怪癖/缺陷:它会默默地丢弃线程中已经存在的任何事件循环,并创建一个新的事件循环来运行主 function。由于 Tornado 在构建应用程序时初始化 autoreload,这意味着它使用在main
之外构造它时的错误事件循环。
有两种可能的解决方案:
asyncio.get_event_loop().run_until_complete()
而不是asyncio.run()
。 这应该按照您期望的方式工作,但这种用法已被弃用,并将在 python 的某个未来版本中删除。asyncio.run()
,但在主 function 中执行所有操作(包括应用程序的构建)。这是未来推荐的模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.