【问题标题】:Python Watchdog issue - missing eventsPython 看门狗问题 - 缺少事件
【发布时间】:2012-10-16 08:16:40
【问题描述】:

我正在使用 Python Watchdog 来监控 Ubuntu 上的文件夹。它适用于 1 或 2 个文件,但是当我通过命令 mv *.xml dest_folder 移动 50 个文件时,它只收到 2 个事件并且只处理 2 个文件。下面是代码。

def on_moved(self, event):
    try:
        logger.debug("on_moved event :" + str(event) )
        self._validate_xml(event.dest_path)
    except Exception as ex:
        logger.exception(ex)

如果我注释掉 _validate_xml 函数,那么我会收到所有 45 个事件。

谁能告诉我看门狗到底发生了什么,最好的解决方案是什么?

【问题讨论】:

  • 对不起,即使评论 _validate_xml 函数它只接收 2 个事件。

标签: python watchdog


【解决方案1】:

我没有使用过 Python Watchdog,但从通用实时系统的角度来看,

  • 使用 _validate_xml 处理 xml 可能会很慢,并且会让您错过事件。
  • event = 类似于中断,处理应该尽可能快。

您在处理事件时做的越多,系统的“实时性”就越低。您可以做的是将 xml 有效性检查卸载到另一个进程并与您看到移动的路径交换消息Queue(消息将是event.dest_path)。您的事件处理将像将消息放入队列一样简单,并且可以由队列的使用者批量处理文件。

简而言之:

  • 实例化Queue
  • fork()进程
  • on_moved 处理程序中,将消息放入队列中,
  • 在分叉的进程中,从队列中弹出消息并调用_validate_xml
  • 您可以选择利用 multiprocessing.Pool 并行验证 xml 文件。

祝你好运。

编辑:在我的系统上测试过;上面的大多数 cmets 似乎都不适用,因为看门狗的代码似乎可以很好地处理 threading

#!/usr/bin/env python

import time
from watchdog.observers import Observer, api
from watchdog.events import LoggingEventHandler, FileSystemEventHandler, FileMovedEvent
import logging


def counter_gen():
    count = 0
    while True:
        count += 1
        yield count

class XmlValidatorHandler(FileSystemEventHandler):
    sleep_time = 0.1
    COUNTER = counter_gen()
    def on_moved(self, event):
        if isinstance(event, FileMovedEvent):
            print '%s - event %d; validate: %s' % (
            type(self).__name__, self.COUNTER.next(), event.dest_path)
            time.sleep(self.sleep_time)

class SlowXmlValidatorHandler(XmlValidatorHandler):
    sleep_time = 2
    COUNTER = counter_gen()

def get_observer(handler):
    observer = Observer(timeout=0.5)
    observer.event_queue.maxsize=10
    observer.schedule(handler, path='.', recursive=True)
    return observer

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    event_handler = LoggingEventHandler()
    observer1 = get_observer(XmlValidatorHandler())
    observer2 = get_observer(SlowXmlValidatorHandler())
    observer1.start()
    observer2.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer1.stop()
        observer2.stop()
    observer1.join()
    observer2.join()

无法重现您的问题。一些指针:

  • 检查队列maxsize,如果您已经有项目并且没有及时处理,那么我的猜测是timeout 启动并且event 丢失了。在这种情况下,您可能需要调整大小。
  • 检查timeout,如果已配置,您可能需要调整该参数。

也许更完整的 sn-p 会帮助我们帮助您。

【讨论】:

  • 您好,感谢您的快速回复。在您提供的代码中,我只是更改了一行observer.schedule(handler, path='./mont', recursive=True)
  • 并通过 mv 命令将 45 个文件放在 mont 文件夹中,我只得到两个处理程序的 2 个事件。下面是打印消息
    *XmlValidatorHandler - 事件 1;验证:/home/devtool/test/mont/invalid_test_invalid_data_type.xlsx SlowXmlValidatorHandler - 事件 1;验证:/home/devtool/test/mont/invalid_test_invalid_data_type.xlsx XmlValidatorHandler - 事件 2;验证:/home/devtool/test/mont/valid_test_offers_terms_HDVOD_SDEST.xlsx SlowXmlValidatorHandler - 事件 2;验证:/home/devtool/test/mont/valid_test_preview_missing.xlsx*
  • 即使将队列的大小更改为 100 也一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多