查看原文
其他

在 Django 中用 watchman 自动检测并重载文件更新

The following article is from Python开发精选 Author 南风草木香

【导语】:watchman 是一个由 Facebook 开发的文件监测器,当 Django 项目中的 Python 文件出现改动时,服务器会通过 watchman 自动重载;而当文件没有变化时,watchman 就停止工作。与常用的 StatReloader 相比,这种工作方式占用较少的CPU运行资源,能够起到保护计算机电池的作用。

简介

如果你在一个Django项目中开启服务器,会出现如下结果:

$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (1 silenced).
January 20, 2021 - 04:25:31
Django version 3.1.5, using settings 'db_buddy.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

当你对其中一个Python文件作出更改时,服务器会自动重载。这一功能由一个文件监测器提供,Django在第一行就给出了默认使用的监测器名字-StatReloader。StatReloader虽然简单,但可靠性却很高。它利用一个循环 在每时每刻对你的所有文件进行检查,然而当开发者的项目内容不断增多时,这种方法就变得十分低效。

一个不太知名却更好的选择是使用 Django 支持的 watchman。

项目地址:
https://facebook.github.io/watchman/

watchman是一个高效的文件监测器,由Facebook开源。它从你的操作系统接收文件更改提示,然后把所有变动集合在一起。当没有更改时,watchman就停止工作,这样就可以节省运行资源,延长计算机电池的寿命。当一旦有文件发生改动时,Django在几毫秒之内快速报告。watchman 处理文件变动的方式也很灵活,它将所有变化信息集中起来,用Git整合,等待诸如分支转换这些流程完成后,再进行处理。

安装

在Django项目中使用watchman只需几步,这在runserver文档[1]中 有详细介绍。在此,我将介绍在macOS上对DB Buddy[2](一个Django 3.1项目)使用watchman的主要过程。

首先,我按照网站上的安装指导[3]对watchman进行了安装。在macoS上,这意味着只需要运行brew install watchman

简单使用

1、我安装了pywatchman,Django使用这个库来与watchman进行交互。

在requirements.in中添加了pywatchman,从而使用pip-tools[4]中的pip-compile来管理我的requirements:

diff --git a/requirements.in b/requirements.in
index c376421..4407458 100644
--- a/requirements.in
+++ b/requirements.in
@@ -28,2 +28,3 @@ pytest-xdist
 python-dotenv
+pywatchman
 requests

2、运行pip-compile,将当前版本的pywatchman固定在requirements.txt中,这样就会产生如下变化:

diff --git a/requirements.txt b/requirements.txt
index 95002f9..5d9073c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -155,2 +155,4 @@ pytz==2020.5
     #   tzlocal
+pywatchman==1.4.1
+    # via -r requirements.in
 requests-mock==1.8.0

然后我运行pip install -r requirements.txt来安装已编译的requirements文件。

3、我创建了一个watchman配置文件,以便忽略我的node_modules目录。Django文档提示,忽略这样的非python目录有助于减少负载。我的项目有一个相对最小的JavaScript配置文件,但在node_modules中仍然有14,303个文件,而所有这些都不需要监测。

根据watchman配置文档[5], 在manage.py旁边创建了一个.watchmanconfig文件,其中包括:

{
  "ignore_dirs": ["node_modules"]
}

4.我重新启动runserver。Django通过在第一行给出watchmanReloader作为文件监视 器,说明它正在使用watchman:

$ python manage.py runserver
Watching for file changes with WatchmanReloader
Performing system checks...

System check identified no issues (1 silenced).
January 20, 2021 - 07:49:15
Django version 3.1.5, using settings 'db_buddy.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

结论

当服务器完全闲置并且不接收任何请求时,我对更改前后的CPU使用情况作了一个快速对比。使用 StatReloader, runserver大概占用 1.6% 的 CPU 处理器;而使用WatchmanReloader,这一数据减少为 0%,使用 watchman 也显示为 0%。效果非常好!

目前这个项目也相对较小,只有 50 个 Python文件和一些附加文件。由于statReloader 的工作与文件的数量成正比,所以在较大的项目中,这种差异只会更加明显。

参考资料

[1]

文档: https://docs.djangoproject.com/en/3.1/ref/django-admin/#runserver

[2]

DB Buddy: https://db-buddy.com/

[3]

安装指导: https://facebook.github.io/watchman/docs/install.html

[4]

pip-tools: https://github.com/jazzband/pip-tools/

[5]

watchman配置文档: https://facebook.github.io/watchman/docs/config#ignore_dirs


- EOF -

推荐阅读  点击标题可跳转

1、Django 实现单点登录(SSO)

2、简约而不简单的 Django 新手图文教程

3、简化 Django 开发的八个 Python 包


觉得本文对你有帮助?请分享给更多人

推荐关注「Python开发者」,提升Python技能

点赞和在看就是最大的支持❤️

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存