[英]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.