0

JVM プログラムの socket/bser インターフェイスを介してウォッチマンを統合しています。

私は奇妙なタイミングを見ています:

  1. ファイルはビルド システムによって書き込まれます (小さなテキスト ファイル)
  2. bser インターフェイスでウォッチマン通知を受け取ります
  3. bser サブスクリプション通知をリッスンするスレッド A は、更新を別のスレッドのキューに入れます。
  4. スレッド B はキューを読み取り、変更されたファイルを読み取り、ファイルのデータをネットワークに送信します。

ただし、どういうわけか、スレッド B は空のファイルを読み込んでいます。

これは、ある時点で有効に空であると想定しています。たとえば、IO/syscalls は次のようになります。

  1. ファイルの内容をクリアする
  2. チャンク 1 の書き込み
  3. チャンク 2 の書き込み
  4. ファイルを閉じる

そして、スレッド B がステップ 1 と 2 の間でファイルを読み取っていると思います。または、4 が結果がフラッシュされたときの場合は、1 と 4 かもしれません。

私の混乱は2つあります。

1)ウォッチマンのデフォルトの20ミリ秒の待機はこのようなことを説明すると思いました.スレッドBが読み取りを行ったときはもちろん、スレッドAの更新のみが表示され、ステップ4の後にデータの書き込みが完了しました.ファイル。

2) ウォッチマンが最初の syscall (ステップ 1 など) について「早すぎる」と言って、それが空のファイルである間に結果を読んだとしても、別の syscall/watchman 通知があるはずです。現在のコンテンツ」。

FWIW/奇妙なことに、Java WatchService API を使用しているときに、これとまったく同じ動作が見られました。ここでは、inotify イベントを取得しましたが、ファイルを「すぐに」読み取ったため、結果が空または部分的になり、フォローアップが行われませんでした。残りのデータが利用可能になったときの inotify イベント。

これは WatchService のまぐれ/ニュアンスであると想定していたので、ファイルを読み取る前に変更時間を確認し、変更時間が 2 秒を超えていることを確認してからファイルが「完了」したと想定することで、その時点で解決しました。 .

(これは、ビルド プロセスが 100 ミリ秒以上ごとにデータのチャンクを書き込む可能性がある場合に、書き込まれる ~100 MB 以上のファイルも処理することに注意してください。ただし、WatchService を使用すると、本質的に単一の連続書き込みであったものに対して数百の inotify 通知が表示されました。)

WatchService コードを watchman に移植したとき、この「ensureSettled」ハックを削除しました。なぜなら、watchman の 20 ミリ秒のセトリング期間 (私が使用していた 2 秒よりもはるかに短いですが、これがデフォルトです) を想定していたからです。 beta の WatchService は、問題にならないことを意味します。

しかし、ウォッチマンに移植されたコードを使用して 1 日以内に、WatchService の場合と同様に、空のファイルの読み取りが見られます。

私が欠けているものについてのアイデアはありますか?

ensureSettled ハックを元に戻すことはできますが、この時点で何が起こっているのか知りたいです。

4

1 に答える 1

0

ドキュメントはこれについてあまり明確ではありません、申し訳ありません!

サブスクリプション通知の送信は解決タイムアウトの影響を受けますが、ファイルの更新はアトミックではないため、ファイルの内容が表示される前にデフォルトの 20 ミリ秒が開始される可能性があります。内部では、カーネルは実行中のさまざまなミューテーションに対して一連の通知を生成するため、データを書き込む (またはおそらくフラッシュする) 前にトランケートに 20 ミリ秒かかる場合、「途中で」通知を受け取る可能性があります。 "。

これもオペレーティングシステムに依存します。最近発見され、解決された問題の例を次に示します 。この議論。

クライアントで決済を管理するコードが既にある場合は、それを追加し直す方が簡単かもしれません。watchman-makeたとえば、これを行います。監視しているディレクトリ ツリーのルートにあるファイルにhttps://facebook.github.io/watchman/docs/config.html#settleを設定.watchmanconfigして、watchman サーバーに任せることもできます。この設定を変更した場合は、時計を削除して再起動する必要があります。

どちらを選択するかは、維持したいコードの量と (おそらく).watchmanconfigが正しく構成されていない場合のユーザー ベースからのサポートの質問の量に対して、構成の容易さをどのようにトレードしたいかによって異なります。

https://facebook.github.io/watchman/docs/cmd/log-level.htmlからのコマンド呼び出しを使用して、リアルタイムで受信するカーネル通知のデバッグ ログを確認できることに注意してください。これは、どの通知がいつ届くかを正確に理解するのに役立ちます。

興味深いことに、 https://github.com/facebook/watchman/tree/master/javaを使用して監視サーバーと通信していますか?

于 2016-09-29T01:28:37.593 に答える