私はUbuntuで作業しており、新しいサブディレクトリとファイルのディレクトリツリーを監視する必要があります。これはrsyncによって埋められ、1秒以内に何百ものファイルを追加できます。いくつかのオプションを検討しています。
オプション1:Pythonのinotify.adapters.InotifyTree()を使用してツリーを監視します。しかし、文書次の警告が含まれています。重要:パスの再帰監視はカーネル提供機能ではありません。代わりに人為的に実装します。ディレクトリ生成イベントが受信されると、すぐにサブディレクトリの監視を生成します。これは潜在的な競争条件があることを意味します。ディレクトリが作成され(event_gen()ループを使用して)、ディレクトリを観察する前にその中にファイルまたはディレクトリが作成されると、問題が発生します。ファイルの場合は、その作成に関連するイベントを見逃すことがありますが、ディレクトリの場合は、その生成イベントを見逃すだけでなく、ライブラリもそれを見逃す可能性があり、その監視を追加する方法はありません。 」
オプション2: '--recursive'オプションを使用して、Linux inotifywatchユーティリティを介してツリーを監視します。この文書次の警告を含めてください: "警告する:大きなツリーのルートを監視するときにこのオプションを使用すると、すべてのinotify監視が設定されるまでにかなり時間がかかる可能性があり、その時点でイベントは受信されません。 」
これら2つのオプションのうち、新しいサブディレクトリとファイルを見逃す可能性が最も低いオプションは何だと思いますか?私の考えでは、inotifywatchが(おそらく)「C」として実装されているので、オプション2はより安定しているようです。ありがとうございます!
答え1
問題を正しく理解することから始めましょう。両方のマニュアルで読み取った警告は、「制限事項と警告」に記載されています。男7イノティファイ:https://man7.org/linux/man-pages/man7/inotify.7.html
これはカーネルの制限が原因であるため、理解することが重要です。両方一部のソフトウェアでは、そのマニュアルに記載されていない場合でも同じ問題が発生する可能性があります。
私の推測では、ほとんどのユーザーには関係がない可能性が高いので、informwatchのマニュアルには競合条件についての言及はありません。 このマニュアルには次の内容が記載されています。:
notifywatch
Linux inotify(7)インターフェースを使用してファイルシステムイベントを受信し、各ファイルまたはディレクトリから受信したイベントの要約数を出力します。
ソフトウェアは、新しいサブディレクトリからいくつかのファイル生成イベントをスキップしても、まだ実行する必要がある作業である統計レポートを実行します。
あなたは何ができますか?
私は両方のソリューションのどちらも必要と思われるほど完璧であると保証できないと思います。すべてが大丈夫だろうとだけ「希望」しないでください!
再inotify 7マニュアルから:
ただし、強力なアプリケーションでは、以下に示す種類の監視ロジックまたは競合エラーが原因でキャッシュがファイルシステムの状態と一致しない可能性があることを考慮する必要があります。一貫性チェックを実行し、不一致が検出された場合は、キャッシュを再構築するのが賢明かもしれません。
あなたの場合は、競争条件の周りのコードで1または2などのオプションを使用するのが賢明でしょう。新しいディレクトリが作成されたことを検出したら、次の操作を行います。
- 新しいディレクトリを書き留めます。
- 利用可能なすべてのinotifyイベントを読むまで待ちます。
- 次に、ディレクトリをスキャン(
pathlib.Path.iterdir()
)して、競合状態のために欠落しているファイルがあるかどうかを確認します。
待つ方法?
利用可能なすべてのinotifyイベントを待つのは難しいです。オプション1(PyPiのinotify)を使用すると、短いタイムアウトで利用可能なすべてのイベントを取得できます。
gen = i.event_gen(yield_nones=False, timeout_s=0.1)
検索する新しいディレクトリがある場合は、タイムアウトを短く設定し、タイムアウトが期限切れになったらそのディレクトリを検索できます。検索する新しいディレクトリがない場合は、タイムアウトなし(タイムアウトなし)この機能を使用できます。