-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
On linux, wrong message while watching a single file and update it #394
Comments
There is a combination of inotify and vim at play here. I'm new to Rust, but have experienced this same behavior with the Go fsnotify package. By verbosely logging all events received, I was able to see that when a file is edited in vim that there swap files that get created and ultimately the inode of the file (which is the actual thing being watched) ends up getting changed. See this stack exchange answer for more detail https://unix.stackexchange.com/questions/36467/why-inode-value-changes-when-we-edit-in-vi-editor. Also keep in mind that frequently vi is aliased to vim based on my experience (i'm not sure if that's distro specific or from sys admins) so that can change how you approach the problem as outlined in the linked stack exchange answer. This appears to be limited to linux as I have tested this case on os x using notify-rs. I watched a specific file, edited it with vi, edited it with vim, even deleted and recreated the file and after all events still received notify events for the file. I can't confirm anything with Windows, but this appears to be how the inotify vs fsevents api works in combination with vi/vim. It is opinion, at least for something that needs to run reliably on linux, that the best practice is to watch a directory instead of specific files and when an event is triggered compare the file name that triggered the event to a list of files you want to watch. |
See also #247 |
Watch a conf file is very common, hope support it. samuelcolvin/watchfiles#235 from typing import Callable
import os
import pathlib
import logging
import traceback
import asyncio
from watchfiles import awatch
async def watch_file_change(
configFilePath: pathlib.Path,
func: Callable
):
"""
监视配置文件变更
"""
assert configFilePath is not None
while True:
try:
assert os.path.isfile(configFilePath)
async for changes in awatch(configFilePath):
logging.warning(f"conf changed! {changes}")
func()
break
except Exception as e:
logging.error(traceback.format_exc())
logging.warning(f"{configFilePath=}")
await asyncio.sleep(120) |
There are many processes, each process only watch their only config file rather than a dir ,because the dir has many config files. |---config_for_proc_1 |
System details
OS/Platform name and version: Ubuntu 20.04.3 LTS
Rust version (if building from source):
rustc --version
: 1.58.1Notify version (or commit hash if building from git): 5.0.0-pre.13
On Linux: Kernel version:Linux version 5.4.0-84-generic
If you're running as a privileged user (root, System):root
What you did (as detailed as you can)
1:I watched a single file:/root/test/6
watch_items [WatchItem path: "/root/test/6", r true, f true] [file_system/src/file_watcher/watcher.rs 218]
2:I modify it via vim
What you expected
Receive Modify event
What happened
I received events as below include Remove event,and then, I could not receive any events of this file even if I watched it again (not restart the program)
eventEvent { kind: Modify(Name(From)), paths: ["/root/test/6"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }
eventEvent { kind: Modify(Metadata(Any)), paths: ["/root/test/6"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }
eventEvent { kind: Remove(File), paths: ["/root/test/6"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }
The text was updated successfully, but these errors were encountered: