gpt4 book ai didi

python - Flask/Werkzeug 调试器、进程模型和初始化代码

转载 作者:太空狗 更新时间:2023-10-29 20:56:46 25 4
gpt4 key购买 nike

我正在使用 Flask 编写一个 Python 网络应用程序。我的应用程序在启动时与另一台服务器建立连接,并在后台定期与该服务器通信。

如果我不使用 Flask 的内置调试器(使用 debug=False 调用 app.run),没问题。

如果我确实使用内置调试器(使用 debug=True 调用 app.run),Flask 会使用相同的代码启动第二个 Python 进程。最终监听 HTTP 连接的是子进程,并且通常表现得像我的应用程序应该的那样,我假设当调试器启动时,父进程就在那里监视它。

然而,这对我的启动代码造成了严重破坏,它在两个进程中运行;我最终有 2 个到外部服务器的连接,2 个进程记录到同一个日志文件,并且通常,它们会相互干扰。

我假设我不应该在调用 app.run() 之前做真正的工作,但是我应该把这个初始化代码放在哪里(我只想在每个 Flask 进程组中运行一次,不管调试器模式如何,但哪个需要在启动时运行并且独立于客户端请求)?

我找到了 this question about "Flask auto-reload and long-running thread"这有些相关,但有些不同,答案对我没有帮助。 (我也有一个单独的长时间运行的线程标记为守护线程,但是当重新加载程序启动时它被杀死了,但我试图解决的问题是在任何重新加载需要发生之前。我不关心重新加载;我关心的是额外的进程,以及避免在父进程中执行不必要代码的正确方法。)

最佳答案

我确认此行为是由于 Werkzeug 而不是 Flask 本身造成的,它与重新加载程序有关。您可以在 Werkzeug 的 serving.py 中看到这一点——在 run_simple() 中,如果 use_reloader 为真,它会通过辅助函数 run_with_reloader()/restart_with_reloader() 调用 make_server,在设置一个 subprocess.call(sys.executable) 之后环境中的环境变量 WERKZEUG_RUN_MAIN 将被子进程继承。

我用一个相当丑陋的 hack 解决了它:在我的主要功能中,在创建 wsgi 应用程序对象和调用 app.run() 之前,我寻找 WERKZEUG_RUN_MAIN:

if use_reloader and not os.environ.get('WERKZEUG_RUN_MAIN'):
logger.warning('startup: pid %d is the werkzeug reloader' % os.getpid())
else:
logger.warning('startup: pid %d is the active werkzeug' % os.getpid()
# my real init code is invoked from here

我有一种感觉,如果在 Werkzeug 开始为它提供服务之前调用一个方法,那么从应用程序对象内部完成会更好。不过,我不知道有这样的方法。

这一切归结为:在 Werkzeug 的 run_simple.py 中,最终只会调用一次 make_server().serve_forever(),但可能有两次调用 run_simple()(整个调用堆栈最多为那一点)在我们到达 make_server() 之前。

关于python - Flask/Werkzeug 调试器、进程模型和初始化代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11571656/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com