簡體   English   中英

Python 在模塊中配置時龍卷風自動重新加載不工作

[英]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 應用程序,但不幸的是,只有在調用startautoreload才有效(同樣,根據 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之外構造它時的錯誤事件循環。

有兩種可能的解決方案:

  1. 使用asyncio.get_event_loop().run_until_complete()而不是asyncio.run() 這應該按照您期望的方式工作,但這種用法已被棄用,並將在 python 的某個未來版本中刪除。
  2. 繼續使用asyncio.run() ,但在主 function 中執行所有操作(包括應用程序的構建)。這是未來推薦的模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM