2

ウォッチマンは構成されたコマンドに投稿できますか?なぜそのコマンドにファイルを送信するのですか?

例えば:

  1. ファイルがフォルダーにとって新しい場合は、FILE_CREATE フラグになる可能性があります。
  2. 削除されたファイルは、FILE_DELETE フラグをコマンドに送信します。
  3. 変更されたファイルは FILE_MOD フラグなどを送信します。
  4. おそらく、フォルダーが削除された場合でも(したがって、その下のファイルが)、フォルダーを指定する FOLDER_DELETE パラメーターと、その下のファイルへの FILE_DELETE / その下のフォルダーへの FOLDER_DELETE が送信されます。

そのようなことはありますか?

4

1 に答える 1

4

いいえ、それはできません。その理由は、その設計にとって非常に基本的なものです。TL;DR は、クライアントがこれらの個々のイベントを正しく処理することは、考えているよりもはるかに複雑であり、ほとんどの場合、実際にはそれらを必要としないということです。

ほとんどのファイル監視システムは、システム固有の通知情報を一般的な形式に単純に変換する抽象化です。彼らは、通知キューがオーバーフローした場合にうまく対処できず、まったく対処できず、その状況に確実に対応する方法をクライアントに提供しません。

これに加えて、ファイルシステムは、非常に短い時間内に、複数の同時スレッドまたはプロセスから、多くのさまざまな変更を受ける可能性があります。これにより、この領域は、管理が困難なTOCTOUの問題が非常に発生しやすくなります。たとえば、ファイルを作成してファイルに書き込むと、通常、ファイルとそのファイルを含むディレクトリに関する一連の通知が発生します。このシーケンスの直後にファイルが削除された場合 (おそらくビルド ステップの中間ファイルであった場合)、ファイルの作成に関する通知が表示されるまでに、ファイルが既に削除されている可能性が高くなります。

Watchman は、通知の入力ストリームを受け取り、それをファイルシステムの内部モデル (監視されたファイルの順序付きリスト) にフィードします。通知が受信されるたびに、watchman はそれを信号として処理し、変更されたと報告されたファイルを調べて、そのファイルのエントリを順序付きリストの最新の末尾に移動します。

Watchman にファイルシステムに関する情報を求めると、カーネルからの保留中の通知がまだある可能性があります。TOCTOU を最小化し、その状態が最新であることを確認するために、watchman は同期 Cookieを生成し、クエリに応答する前にその通知が表示されるのを待ちます。

上記の 2 つの組み合わせは、ウォッチマンの結果データに 2 つの重要なプロパティがあることを意味します。

  1. クエリの前に発生したすべての通知を確認したことが保証されています
  2. 特定のファイルの最新情​​報は、クエリ結果で 1 回だけ受け取ります (変更結果は結合されます)。

オーバーフローのケースについて話しましょう。システムがファイルの変更速度についていけない場合 (たとえば、大きなプロジェクトがあり、ファイルの作成と削除を非常に迅速に行っており、システムの負荷が高い場合)、OS は保留中のすべてのファイルに対応できません。監視に割り当てられたバッファ リソース内の通知。それが発生すると、それらのバッファを吹き飛ばし、オーバーフロー シグナルを送信します。これは、監視 API のクライアントがいくつかのイベントを見逃しており、ファイルシステムの状態と同期していないことを意味します。そのクライアントがファイルシステムに関する状態を維持している場合、それはもはや有効ではありません。

Watchman は、監視対象のツリーを再調査し、すべてのファイルを変更済みとして総合的にマークすることで、この状況に対処します。これにより、クライアントからの次のクエリでツリー内のすべてが表示されます。初めてクエリを実行したときに得られるビューと同じであるため、これを新しいインスタンスの結果セットと呼びます。結果にフラグを設定して、クライアントがこれが発生したことを認識し、適切な手順を実行して自身の状態を修復できるようにします。この動作は、クエリ パラメータを使用して構成できます。

これらの新しいインスタンスの結果セットでは、特定のファイルが実際に変更されたかどうかはわかりません ( を介して検出できない方法で変更された可能性がありますlstat)。メタデータが変更されたことがわかったとしても、その変化の原因はわかりません。

特定のファイルがウォッチマンによって配信される結果に表示される理由に寄与する複数のイベントが存在する可能性があります。無制限の履歴でそれらを追跡できないため、それらを個別に記録しません。1 日中 1 秒ごとにインクリメンタルに書き込まれるファイルを想像してみてください。1 日あたり 86400 の変更エントリを手元に保管し、それらをクライアントに配信しますか? このようなファイルが何十万もある場合はどうなりますか? そのデータを切り詰める必要があり、その時点でデータが失われると、それについてどれだけうまく推論できるかが低下します.

これらすべての最後に、クライアントがファイルを読み取ったり、そのメタデータを調べたりする以上のことを行うことは非常にまれであり、一般的に言えば、クライアントはファイルの変更が停止したときにのみそれを実行したいと考えています。この使用例では、watchman-waitwatchman-make、およびtriggerのすべてに、ファイルシステムの変更が停止するまで変更通知の配信を遅らせる解決期間の概念があります。

于 2016-03-02T17:01:04.397 に答える