ADR-0002: 常駐デーモンを持たない
状態: Accepted
文脈
CLI は短命プロセスであり、増分クエリグラフをプロセス間で保持する方法を決める必要がある。
| 方式 | 例 | 利点 | 欠点 |
|---|---|---|---|
| デーモン常駐 | Bazel, Buck2, Gradle | メモリ上のグラフを再利用。言語サーバと自然に統合 | ライフサイクル管理、資源占有、状態の陳腐化 |
| ディスクへの直列化 | rustc incremental | 常駐なし。挙動が理解しやすい | 復元コストがかかる |
決定
常駐デーモンを持たない。状態の正本はディスク上のストアに置く。
podman が daemonless であることによって支持を得ている構図を参照する。 参照すべき点は2つ。状態の正本がディスク上のストアにあり CLI が自己完結すること、 および特権を要求しないこと。後者は将来の sandbox 設計にも効く。
Gradle デーモンに対する評価も、常駐を選ばない根拠として無視できない。
根拠
- mmap と OS ページキャッシュの組み合わせが、実質的に常駐の代替となる。 2回目以降の起動ではページキャッシュに載っており、読み出しコストはメモリ上のグラフに近づく。 常駐を避けることの代償の大部分はこの一点で回収できる
- 一括直列化・一括復元を避け、復元コストを O(触れたノード) にすれば rustc incremental の弱点を回避できる
帰結
- ストアは mmap 可能な固定長レコードのインデックス + 追記専用の値ログとする
- 変更検出は
stat走査(ファイル監視を使わない) - 書き手は
flockで単一に制限。取得できなければキャッシュを書かずに計算する。 正しさは失われず、利得のみを失う - 起動時間が毎回課金される。無操作時 10ms 以下を目標とし、実装言語選択の制約となる
- 追記専用ストアの GC が必要
- 言語サーバは例外ではない。エディタが起動主体でありエディタと共に終了するため、 デーモンとは区別される。ただし CLI は言語サーバの存在に一切依存しない
- 数十万ノード規模ではインデックス検証コストが支配的になり不利。 想定規模をターゲット数 10^3〜10^4 に限定する