在代码中重启Django程序
最近在 Qexo 的编写过程中,遇到了一个问题:
如何在完成更新后让程序自动重启?
这个问题困扰了我一段时间,起初使用的是 Django 自带的 AutoReloader,但效果并不佳,经常没有完成文件的完全替换就自动重启,从而导致更新失败。在参考了部分大佬的文章之后,总结出了一个不错的方法。
关闭自动重载
既然我们要把程序的重启完全掌握在自己手中,那么必须要提前关闭好程序的自动重载功能,这一点十分简单,只需要稍微修改启动命令即可
1 | python3 manage.py runserver --noreload |
只需要加上--noreload
参数即可禁用 Django 的 AutoReloader
添加重载代码
结论
先说结论,如果在程序中你需要重载,则需要强制退出子程序并返回“3”作为退出代码,即
1 | import os |
这是如何实现的?
经过一番搜索之后,我并没有找到哪个大佬给出了完整的方案(也有可能是我搜索能力较弱),于是在结合了Django源码分析对于 Reloader 的分析给出了这个解决方案
我们观察django.utils.autoreload
中有关重启的代码,经过筛选后得到:
1 | def restart_with_reloader(): |
发现 Django 的运行逻辑并不是直接使用主进程,而是创建了一个子进程来执行程序代码,而由原本的进程来实现守护
我们需要重启子线程,就需要让子进程结束,我们观察到如果退出代码不为“3”则结束程序,为“3”则继续运行,重新执行循环来创建子进程,这就是我们需要的
进程自杀的代码为:
1 | import sys |
但是很遗憾,这个代码中 sys 库会先抛出一个错误,而这个错误会被 Django 捕获而无法退出,所以我们需要一个更加严厉的退出方法
1 | import os |
经过尝试,这个代码完美地符合了我们的要求,主程序遇到“3”作为退出代码后重新创建了一个新的进程,完结撒花
在代码中重启Django程序