当 Flask 在调试模式下重新启动时挂钩

Bri*_*unt 5 python werkzeug flask

在调试模式下使用 Flask/Werkzeug 时,我在线程中打开了许多文件(使用watchdog),我想关闭这些文件,否则我最终会开始获取OSError: too many files. 我想在 Flask/Werkzeug 在调试模式下关闭之前运行一个钩子(顺便说一句,observer.stop()来自Watchdog 文档observer.join())。

从文档或源代码中尚不清楚哪里可以做到这一点。

看起来重启是围绕run_with_reloader中的函数发生的Werkzeug/serving.py:523。似乎没有任何方法可以通过公开的 API 挂接到这里。

在进程重新启动之前调用一些代码来获取线程的最佳方法是什么?

Ôre*_*rel 3

我想我已经找到了解决这个问题的方法。该问题来自第一次 werkzeug 重新加载,说明它将使用哪个文件监视程序,记录如下内容:

* Restarting with inotify reloader"
Run Code Online (Sandbox Code Playgroud)

重新加载是通过 a 完成的subprocess.call,因此我们有2 个不同的 Python 解释器同时运行!

在其他重新加载(文件更改时)上,有一个很好的优势,子进程在启动新进程之前被终止,相当残酷,但完成了工作:

这是在 werkzeug 上如何完成的:

        sig = getattr(signal, "SIGKILL", signal.SIGTERM)
        # reloader active
        if is_running_from_reloader():
            os.kill(os.getpid(), sig)
Run Code Online (Sandbox Code Playgroud)

我的解决方案是,当我使用 werkzeug 时(当 app.debug 在我的情况下为 true 时)并且仅在重新加载的子进程上执行后台线程 init 。is_running_from_reloaderwerkzeug 提供了函数来了解你处于子进程中

进入app/__init__.py

if not app.debug or app.debug and werkzeug.serving.is_running_from_reloader():
    # do what you want to do at start up
Run Code Online (Sandbox Code Playgroud)

在其他地方,对我来说进入课堂,在退出时进行清理(当进程被杀死时)

class MyClass:
    @classmethod
    def cleanOnExit(cls):
        # do here your cleaning
import atexit ; atexit.register(MyClass.cleanOnExit)
Run Code Online (Sandbox Code Playgroud)