Skip to content

fix(pi-fff): non-blocking session_start warmup#599

Open
gustav-fff wants to merge 1 commit into
mainfrom
triage-bot/issue-477
Open

fix(pi-fff): non-blocking session_start warmup#599
gustav-fff wants to merge 1 commit into
mainfrom
triage-bot/issue-477

Conversation

@gustav-fff

Copy link
Copy Markdown
Collaborator

Closes #477

Root cause

packages/pi-fff/src/index.ts session_start handler awaited ensureFinder()finder.waitForScan(15000). Pi recreates the session runtime on /new and /resume, so the lifecycle hook blocked the UI until the FFF initial scan finished (up to 15s on large workspaces).

Fix

  • Schedule ensureFinder(activeCwd) from session_start via setTimeout(0) instead of awaiting it. The handler returns immediately; the warmup runs in the background.
  • Track a monotonic lifecycleId, bumped on every session_start and session_shutdown. The deferred warmup checks the captured id and bails out (no ensureFinder, no ctx.ui.notify) if the session has been replaced.
  • ensureFinder returns the local created handle instead of the mutable finder global, so a destroyFinder() racing the warmup cannot hand back a destroyed/replaced instance to the caller.

The native SDK already exposes waitForScan as a non-blocking polling loop (packages/fff-node/src/finder.ts:477), so no SDK changes were needed — only the lifecycle hook.

Steps to reproduce

Pre-fix, on main:

git checkout main
cd packages/pi-fff
# Run pi with the extension installed against a large workspace (e.g. chromium / linux)
pi
# In pi: type /new and press Enter

Expected: new session is interactive immediately.
Actual (pre-fix): UI hangs for up to 15s while FileFinder.create + initial scan runs inside session_start. Same hang on /resume after picking a session.

Post-fix: /new and /resume return instantly. The first ffgrep / fffind / @-mention call awaits the same in-flight ensureFinder promise as before.

How verified

  • bun test test/ in packages/pi-fff — all 17 tests pass (test helper updated to flush the deferred warmup before asserting).
  • tsc --noEmit produces only the pre-existing module-resolution errors (unchanged from main).
  • Manual code review of the lifecycle race: shutdown during warmup is safe because the deferred callback short-circuits on stale lifecycleId, and ensureFinder returns the local handle.

Automated triage via Gustav. Honk-Honk 🪿

Schedule FileFinder.create + waitForScan via setTimeout(0) so Pi /new and
/resume return immediately. A monotonic lifecycleId tagged on each
session_start / session_shutdown lets a stale warmup detect that the
session has been replaced and skip both ensureFinder and ctx.ui.notify.
ensureFinder now returns the local handle so a shutdown mid-warmup can't
hand back a destroyed/replaced finder.

Closes #477
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pi-fff blocks Pi /new and /resume while waiting for FileFinder scan on session_start

1 participant