リモート Mac クラスタの monorepo 並列ビルドで FSEvents のイベントストームが先に詰まる例。M4+watchman でも根が広いと通知雪崩でインクリ不安定。マトリクスとしきい値で整理。
watchman と git ポーリングの対照
watchman は監視を集約しデバウンス済みで渡す。git ポーリング型は間隔を詰めるとメタデータ I/O が跳ねるが、デーモンを増やさず済む場面もある。
| 観点 | watchman 優位 | git ポーリング/軽量ポーリング |
|---|---|---|
| レイテンシ | 大ツリーでも低レイテンシを狙いやすい。 | 間隔依存。短いとメタデータ I/O が増える。 |
| イベントストーム耐性 | settle(ms)と fsevents_latency(秒)で平滑化可能。 |
バースト時はフルスキャンに近づく実装があり上限必須。 |
| 多ノード運用 | ノード毎にローカルデーモン。NFS 上は不安定になりやすい。 | 共有 FS は狭いサブツリー+ポーリングが安全なことも。 |
しきい値:ignore_dirs 済みでも通知が秒数百超なら根分割と CORE_WATCHMAN=0 の A/B を。
sysctl/fs 制限と Watchman の節流パラメータ
裏ではディスクリプタ枯渇とキュー詰まりが同居。kern.maxfiles 系は並列度×監視ファイルの関数のため、ツリーを狭げず sysctl だけでは再発する。
sudo sysctl kern.maxfiles=524288 sudo sysctl kern.maxfilesperproc=262144
// .watchmanconfig — fsevents_latency は秒
{
"fsevents_latency": 0.05,
"settle": 200,
"ignore_dirs": ["node_modules", "dist", ".turbo"]
}
節流:再キュー 100〜300ms、バースト 500ms。通知/秒・キュー・EMFILE を同ダッシュへ。
大倉(monorepo)ビルドロックとの協働
監視は起動タイミング、書き込み主体は別。スケジューラの単一昇格+flock の二段で watchman 連打をビルドロックが吸収。
LOCK_FILE="/var/tmp/monorepo-incremental.lock"
flock -n "$LOCK_FILE" bash -c 'pnpm exec turbo run build --filter=...' \
|| { echo "incremental busy"; exit 19; }
役割分担は Nomad 稿。終了 19=ロック競合をメトリクス分離。
ディスク水位:1TB/2TB のアラート値と受入チェックリスト
ストームはinode/メタデータ I/Oを食うが、受入は容量相対率+絶対空き GBの併記が安全(2TB でも誤判定減)。
| シグナル | 推奨アラート | 受入アクション |
|---|---|---|
| 緑 | 使用率 <70%、空き ≥150GB(1TB)/≥200GB(2TB) | 通常運用。 |
| 黄 | 70〜80% または空きが上記を 48h 下回る | キャッシュ整理・重い pipeline 抑止。 |
| 赤 | ≥85%(警告)/≥90%(クリティカル) | 増設最優先。同期帯域と watch 根を縮小。 |
受入:キャッシュ削除ドライラン記録、85%→解放 MTTR を SLO 化、2TB+シミュレータ多版は黄を約 5% 早める。
70%
クリーン分水嶺
85%
黄赤境界
90%
投入ストップ
運用目安。 値は Watchman/OS で差あり。ステージング M4 で再現し
EMFILE と完了率を同視。