5

Python Watchdog を使用して、Ubuntu のフォルダーを監視しています。1 つまたは 2 つのファイルでは正常に動作していますが、コマンドで 50 個のファイルを移動するmv *.xml dest_folderと、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 個のイベントすべてを受け取ります。

ウォッチドッグで正確に何が起こったのか、そしてこれに対する最善の解決策は何か教えてもらえますか?

4

1 に答える 1

6

私は Python Watchdog を使用していませんが、一般的なリアルタイム システムの観点から、

  • xml の処理_validate_xmlが遅くなる可能性があり、イベントを見逃す可能性があります。
  • イベント = 割り込みと同様に、処理は可能な限り高速にする必要があります。

イベントの処理中に多くのことを行うほど、システムは「リアルタイム」ではなくなります。あなたができることは、xml の有効性チェックを別のプロセスにオフロードし、Queue(メッセージはevent.dest_path) とメッセージを交換することです。イベント処理はメッセージをキューに入れるのと同じくらい簡単で、ファイルはキューのコンシューマによってバッチで処理できます。

要するに:

  • インスタンス化するQueue
  • fork()処理する
  • on_movedハンドラーで、メッセージをキューに入れ、
  • フォークされたプロセスで、キューからメッセージをポップし、 を呼び出します_validate_xml
  • オプションmultiprocessing.Poolで、xml ファイルを並行して検証することもできます。

幸運を。

編集:私のシステムでテストしました。上記のコメントのほとんどは当てはまらないようです。ウォッチドッグのコードは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()

問題を再現できませんでした。いくつかのポインタ:

  • check queue maxsize、すでにそこにアイテムがあり、それらがタイムリーに処理されない場合、私の推測では、timeoutキックが開始されてevent失われます。その場合、サイズを変更することをお勧めします。
  • 構成timeoutされている場合は、そのパラメーターを調整することをお勧めします。

たぶん、より完全なスニペットがあなたを助けるのに役立つでしょう.

于 2012-10-16T08:55:45.563 に答える