refactor: search.ts の scan 系 IPC を bounded-concurrency parallel readFile 化 (#249)#250
Merged
Merged
Conversation
…ile 化 (#249) - searchFilesImpl / scanUnresolvedWikilinksImpl / scanBacklinksImpl の per-file await fsp.readFile() for ループを module-level 共有 pLimit(16) で並列化 - backlink panel refresh / 全文検索 / 未解決リンク走査 (user-facing hot path) の wall-clock を 5-20x 改善見込み (N=tens〜low-thousands、I/O dominant) - 複数 scan IPC が同時並行しても同時 fd 数を 16 に抑えるため module-level に ioLimit を 1 つ作って 3 関数で共有 - searchFilesImpl は事前 order 配列を廃し、最終 results.sort((filePath, lineNumber, matchStart)) で旧 sequential 実装の出力順序を再現 - scanUnresolvedWikilinksImpl / scanBacklinksImpl は元から最終 sort 済 (pageName / sourceFile 昇順) のため追加 sort 不要 - isStale check は各 task 開始時に 1 回 + Promise.all 後の最終 check に集約 (旧 sequential の per-iter check と等価方針 + 後段の sort/map 変換コストを skip) - e2e mock (e2e/helpers/electron-api-mock.ts) は in-memory store.files[path] 経由 で I/O 非該当 → 並列化対象外、symmetry 対応不要 - p-limit は既に transitive deps として 3.1.0 が存在したため direct deps 化のみで 新規 download なし
- 3 関数 (searchFilesImpl / scanUnresolvedWikilinksImpl / scanBacklinksImpl) の各並列 task で readFile の await 中に stale 化していた場合、後続の重い CPU 処理 (per-line scan / iterateWikilinkOccurrences の parse) を skip して cancel 反応性を上げる - /simplify 2 回目 Efficiency reviewer 指摘 (cancel mid-batch で parse work が 走り切る) への対応、1 行追加 × 3 箇所
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
electron/main/ipc/search.tsの 3 つの scan 系 IPC (全文検索 / 未解決 wikilink 走査 / バックリンクパネル refresh) の per-fileawait fsp.readFile()for ループを module-level 共有pLimit(16)で並列化。N=tens〜low-thousands のワークスペースで wall-clock 5-20x 改善見込み (qualitative、I/O dominant)。backlink panel refresh など user-facing な hot path の応答性向上が目的。
関連 Issue
closes #249
移行 Stage
(該当なし — 既存機能のリファクタリング、Stage 3 領域)
変更内容
electron/main/ipc/search.tsのsearchFilesImpl/scanUnresolvedWikilinksImpl/scanBacklinksImplの per-fileawait fsp.readFile()for ループをPromise.all(... ioLimit(async () => {...}))で並列化const ioLimit = pLimit(16)を 3 関数で共有 (cross-IPC でも同時 fd 数を 16 に維持)searchFilesImplは事前order配列を廃止、最終results.sort((filePath, lineNumber, matchStart))で旧 sequential 実装の出力順序を再現scanUnresolvedWikilinksImpl/scanBacklinksImplは最終出力で既に sort 済 (pageName / sourceFile 昇順) のため追加 sort 不要readFile後 (重い CPU 処理 = per-line scan /iterateWikilinkOccurrencesの前) にif (isStale()) return;を配置 → cancel 反応性を旧 sequential 実装と同等以上に保つPromise.all後にもif (isStale()) return [];を追加 (後段の sort / map 変換コストを skip)package.jsonに"p-limit": "^3.1.0"direct deps 追加 (既に transitive deps として 3.1.0 が存在、新規 download なし)e2e/helpers/electron-api-mock.ts) は in-memorystore.files[path]経由で I/O 非該当 → 並列化対象外、symmetry 対応不要動作確認
pnpm typecheck/pnpm typecheck:e2epassbiome checkclean (本 PR で touch した file のみ)pnpm test2230 pass / 2 skip (regression なし)electron/main/ipc/search.test.ts93 pass (cancel / cross-cancellation guard / 出力順序の test 全て pass)/code-review low + /simplify 結果
/code-review low:(none)(runtime-correctness bugs なし)/simplify1 回目 (commit80717e0前): 採用 1 件 (コメント簡素化)、見送り 9+ 件/simplify2 回目 (commit80717e0後): 採用 1 件 (Efficiency reviewer 指摘 =readFile後の追加isStalecheck、commit5f04468で対応)、残り見送りは 1 回目と同根拠見送りした主な指摘 (両セッション共通)
readMdFilesWithLimithelper に抽出 (Reuse / Simp / Alt)Promise.all後のif (isStale()) return [];削除 (Simp)SCAN_IO_CONCURRENCYconstant 切り出し /electron/main/utils/io-limit.tsに export (Alt)results.sort()を bucket per-file 配列 + concat に置換 (Eff)io.map(...)の N Promise 一斉作成を worker pool で O(16) 化 (Eff)スクリーンショット
UI 変更なし。