Newer
Older
TelosDB / docs / plans / folder_monitor / folder_monitor_02_tech.md

フォルダ監視: 02 技術方針

計画トップ


3.0 設計: 監視プロトコルとドライバ

方針: 監視の「やり方」を共通プロトコル(トレイト/インターフェース)で定義し、OS・ファイルシステム・ネットワーク種別ごとにドライバを用意する。

  • プロトコル(共通インターフェース)
    • 監視の開始・停止、イベントの購読など、呼び出し側が依存する操作だけを定義する。
    • 例: watch(path, recursive) → ハンドル、EventStream またはコールバックで Create / Remove / Modify を受け取る、unwatch / stop
  • ドライバ
    • 上記プロトコルを実装する。中身は 03 OS・プロトコル別 のマトリクスに沿い、ネイティブ監視(RecommendedWatcher)かポーリング(PollWatcher)のどちらか+設定で表現する。
    • 実装の切り口は「OS×ネットワーク」の全組み合わせを個別クラスにする必要はなく、バックエンド 2 種で足りる:
      • ネイティブドライバ: notify::recommended_watcher() + デバウンス。中で OS 別 API(ReadDirectoryChangesW / FSEvents / inotify)は notify が担当。
      • ポーリングドライバ: PollWatcherConfig(poll_interval, 必要なら compare_contents)。ネットワーク FS・WSL・擬似 FS 等で使用。
    • ドライバ選択(セレクタ): パスと実行環境(OS・マウント情報など)から、上記どちらのドライバ(およびオプション)を使うかを決める。選択ロジックは 03 の「プロトコル・ストレージ種別の判定」にまとめる。
  • 効果
    • 上位(DB 連携・設定 UI)はプロトコルだけに依存し、OS やネットワークの違いを意識しない。
    • 新たな環境(別 OS や新しいネットワーク FS)への対応は、セレクタの判定と必要なら新ドライバ(または既存ドライバの設定)の追加で済む。

3.1 監視ライブラリ: notify

  • 採用: Rust の notify クレート(現行安定版 8.x、crates.iodocs.rs)を採用する。クロスプラットフォームで同一 API が使え、各 OS のネイティブ API を利用する。
  • バックエンド(プラットフォーム別):
    • Windows: ReadDirectoryChangesW
    • macOS: FSEvents(デフォルト)。feature macos_kqueue で kqueue に切り替え可能。
    • Linux / Android: inotify
    • BSD 系: kqueue
  • 推奨 Watcher: notify::recommended_watcher() で、そのプラットフォームに最適な実装(RecommendedWatcher)を取得する。イベント駆動で CPU 負荷が低い。
  • イベント種別: EventKindCreate, Remove, Modify 等を区別して扱う。RecursiveMode::Recursive でサブディレクトリも監視可能。

3.2 デバウンス

  • 目的: 同一ファイルへの短時間の連続変更(エディタの自動保存・一括書き換え等)を、1 回の「更新」にまとめる。
  • 手段: notify-debouncer-minidocs.rs)を利用する。new_debouncer(Duration::from_secs(2), callback) のように時間幅を指定し、その間のイベントを集約してコールバックに渡す。
  • 代替: より高度な処理(Rename の追跡・重複 Create の除去等)が必要なら notify-debouncer-full を検討する。TelosDB では「追加・削除・更新」の 3 種で十分な場合は mini で足りる。
  • 注意: debouncer-mini は内部でスレッドを使いブロッキング受信するため、Tauri の async ループからは spawn_blocking や専用スレッドでラップし、結果をチャンネルで async 側に渡す構成が無難。

3.3 ネットワークフォルダ・フォールバック

  • 公式の既知問題notify Known Problems):
    • ネットワークマウント(NFS 等): 多くのネットワーク FS ではネイティブの変更通知が発火しない。WSL 上で Windows パスを監視する場合も同様(issue #254)。
    • 対処: PollWatcher バックエンドを使う。notify::Config::default().with_poll_interval(Duration::from_secs(30)) でポーリング間隔を指定し、notify::WatcherKind::PollWatcher で明示的に PollWatcher を生成する。デフォルトのポーリング間隔は 30 秒。大容量ツリーでは負荷が高いため、間隔の調整や「ネットワークパス用」の別ワッチャーとして扱う設計がよい。
  • その他で PollWatcher が推奨されるケース: Docker on macOS M1(Function not implemented)、/proc/sys などの擬似 FS、macOS で「自分が所有していないファイル」を FSEvents で追う場合(FileSystemEventSecurity)。
  • 実装方針: まずは RecommendedWatcher で監視を開始し、ネイティブ監視が失敗するか、ネットワークパスであることを検出した場合に、同じ設定オブジェクトで PollWatcher に切り替えるフォールバックを用意する。ネットワークパスかどうかは、パスがマウントポイントか、または watch 登録時のエラー種別で判断する。

3.4 プラットフォーム別の注意点

  • Linux: inotify の上限
    • max_user_watches(デフォルト 8192、カーネルによっては 1048576)を超えると「No space left on device」や「upper limit on inotify watches reached」が出る。再帰監視では「監視対象ディレクトリ内のファイル・フォルダ数」がそのまま watch 数に効く。
    • 対処: ユーザーに sysctl fs.inotify.max_user_watches=524288 等の増設を案内するか、監視対象が大きい場合は初めから PollWatcher を使う選択肢を設ける。PollWatcher は inotify の上限に縛られない。
  • macOS: サンドボックス
    • サンドボックス環境では、監視できるパスが権限付与された範囲に限られる。Accessing files from the macOS App Sandbox に従い、必要なら com.apple.security.temporary-exception.files.home-relative-path.read-only 等の entitlement を検討する。Tauri アプリがサンドボックスを有効にする場合、ユーザーが「監視フォルダ」を選択したパスがその例外に含まれるようにする必要がある。
  • エディタの保存挙動
    • 編集ツールによっては「上書き保存」で truncate して書き直すため、Notify では Remove + Create や複数回の Modify に見えることがある。デバウンスと「同一パスは最後のイベントで 1 回だけ再取り込み」とする方針で吸収する。

3.5 Config とオプション(notify)

  • Config::with_poll_interval(dur): PollWatcher 用。再スキャン間隔(デフォルト 30 秒)。ツリーが大きい場合は 60 秒などに延ばす検討。
  • Config::with_compare_contents(true): PollWatcher 用。変更検知を mtime ではなくファイル内容のハッシュで行う。/proc 等で有効。通常のローカル/ネットワークではオフでよい(パフォーマンス影響大)。
  • Config::with_follow_symlinks(bool): シンボリックリンクをたどって監視するか。デフォルトは true。同一実体の二重登録を防ぐなら false にする選択肢がある。

3.6 既存機能との連携

  • 方向: 監視 → DB の一方向。検出イベントを内部の取り込みパイプラインに渡すだけでよく、MCP や HTTP API へ「新規追加しました」などを能動的に通知(プッシュ)する仕様は設けない。クライアントは必要時に search_textget_document_count 等で現在状態を取得すれば足りる(01 スコープ)。
  • 追加: 新規ファイル検知 → 既存の文書取り込みパイプライン(チャンク分割・ベクトル化・documents / items / vec_items / FTS 登録)を呼び出す。
  • 更新: 変更検知 → 当該パスに紐づく既存ドキュメントを更新(再取り込み)する。
  • 削除: 削除検知 → 当該パスに紐づくドキュメントを documents から削除(関連 items / vec_items / FTS も連動削除)。
  • 親フォルダ削除: notify の仕様上、/a/b/ 以下の削除イベントを受け取るには親 /a を watch する必要がある。再帰監視では通常その前提が満たされるが、直下のみ監視する場合は注意する(notify ドキュメント)。

3.7 設定の保存

  • 監視対象フォルダパス・再帰の有無・対象拡張子・監視オン/オフは、アプリの設定(Windows は %APPDATA%\com.telosdb.app\、macOS/Linux は各 OS のアプリ設定ディレクトリ、または既存の localStorage と連携する API)に永続化する。
  • 設定変更時に、監視ワッチャーを再起動(購読パスの付け替え)する。
  • パス表記: プラットフォームごとのパス形式(Windows の C:\、macOS/Linux の /、ネットワークの ///mnt/ 等)をそのまま保存し、実行環境に応じて正しく解釈する。