from watchdog.events import PatternMatchingEventHandler
handler = PatternMatchingEventHandler(patterns=['*.conf'], ignore_patterns=['*.swp', '*~'])
# 回调里按 event.src_path 做 300ms 去抖

监听目录里改一行配置,处理函数被调了三次,日志里三条 modified 时间差 12 毫秒。任务被重复排队,下游接口报幂等冲突。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,编辑器保存常是先写临时文件再 rename,还会改权限或写备份,内核会分别发 created、moved_to、modified 事件。watchdog 把这些原样抛给回调,没有合并窗口。

围绕「watchdog 重复事件」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

处理上按这个顺序:按路径维护上次处理时间 300 毫秒内的事件直接丢弃;只关心 moved_to 或 close_write 这类终态事件;用事件去抖队列 定时取最新一条执行;处理函数本身做成幂等 重复触发也不会出错。

改完只确认一件事:再保存一次配置 处理日志只有一条 任务队列里没有重复项。

作者 9823189