Skip to content

fix(pi-fff): cache sdk import across reloads to avoid /reload hang - #758

Merged
dmtrKovalenko merged 1 commit into
dmtrKovalenko:mainfrom
chenydev:fix/pi-fff-sdk-import-hang-on-reload
Aug 9, 2026
Merged

fix(pi-fff): cache sdk import across reloads to avoid /reload hang#758
dmtrKovalenko merged 1 commit into
dmtrKovalenko:mainfrom
chenydev:fix/pi-fff-sdk-import-hang-on-reload

Conversation

@chenydev

@chenydev chenydev commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Closes #757

Root cause

Pi reloads extension modules with jiti moduleCache: false, so loadSdk() in packages/pi-fff/src/sdk.ts re-executes a dynamic import("@ff-labs/fff-bun") on every /reload. The fff-bun module graph top-level awaits a type: "file" import of the native libfff_c.so (packages/fff-bun/src/embedded.ts), which never resolves when re-imported inside the Bun-compiled pi binary. Since pi awaits all session_start handlers without a timeout, the reload screen sticks on "Reloading keybindings..." forever (CPU ≈ 0).

The first import at startup resolves fine (~20ms); plain bun re-imports also work — the hang is specific to the pi Bun binary + jiti combination.

Fix

Cache the first import on globalThis so reloads reuse the resolved module instead of re-importing:

const g = globalThis as Record<string, unknown>;
if (g.__fffSdkPromiseGlobal) {
  sdkPromise = g.__fffSdkPromiseGlobal as Promise<{ FileFinder: FileFinderStatic }>;
  return sdkPromise;
}
...
sdkPromise = p;
(globalThis as Record<string, unknown>).__fffSdkPromiseGlobal = p;

Verification

Reproduced in an isolated env (copied agent dir + PI_CODING_AGENT_DIR, PTY driver):

  • Before: /reload stuck >60s, no "Reloaded keybindings" line, process at ~0% CPU.
  • After: 3 consecutive /reload calls all succeed in ~2s with the full 28-package user settings.

Note: #599 (non-blocking session_start warmup) would mask the UI hang, but the background import would still hang and break subsequent fff tool calls, which await the same in-flight sdkPromise. This import-level fix is complementary.

Pi reloads extension modules with jiti moduleCache:false, so loadSdk()
re-executes a dynamic import of the fff-bun module graph on every /reload.
The fff-bun graph top-level awaits a type:file import of the native .so,
which never resolves when re-imported inside the Bun-compiled pi binary,
leaving the reload screen stuck forever (pi awaits session_start handlers
without a timeout).

Cache the first import on globalThis so reloads reuse it.

Closes dmtrKovalenko#757
@dmtrKovalenko
dmtrKovalenko merged commit d4c416c into dmtrKovalenko:main Aug 9, 2026
52 checks passed
abhijit-s pushed a commit to abhijit-s/fff that referenced this pull request Aug 10, 2026
Upstream (6 commits): rescan throttling for giant folders (dmtrKovalenko#751), configurable
$HOME scanning (dmtrKovalenko#743/dmtrKovalenko#749), Lua-level fs-root/home guard (dmtrKovalenko#745/dmtrKovalenko#748), pi-fff
SDK import cache (dmtrKovalenko#758), release 0.10.3.

Conflict resolution:
- Cargo.toml/Cargo.lock (all crates): keep fork's 0.17.2 version scheme over
  upstream's 0.10.3; preserve fff-mcp's fff-ipc/dirs/libc deps and upstream's
  new rescan-stats feature.
- Makefile: union of fork's daemon/install targets and upstream's
  test-rescan/rescan-probe targets.
- install-mcp.sh: keep fork's removal of the pinned-release SHA block
  (delivery is via Homebrew tap + apt, not pinned GitHub tarballs).
- background_watcher.rs: adopt upstream's throttled try_trigger_full_rescan
  mechanism wholesale, keeping only the fork's per-root user_gi ignore filter;
  drop the obsolete need_full_rescan boolean.
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 hangs Pi /reload forever — re-import of fff-bun module graph never resolves in the Bun binary

2 participants