Skip to content

fix: decouple slow services from InstanceBootstrap critical path#23408

Open
codeg-dev wants to merge 8 commits intoanomalyco:devfrom
codeg-dev:fix/bootstrap-decouple-watcher-vcs
Open

fix: decouple slow services from InstanceBootstrap critical path#23408
codeg-dev wants to merge 8 commits intoanomalyco:devfrom
codeg-dev:fix/bootstrap-decouple-watcher-vcs

Conversation

@codeg-dev
Copy link
Copy Markdown

@codeg-dev codeg-dev commented Apr 19, 2026

Issue for this PR

Closes #23409

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

This fixes slow cold project opens on external macOS volumes by removing two long-running operations from the request path.

  • cherry-picks the existing rev-list timeout fallback so project ID discovery no longer stalls for several seconds
  • keeps InstanceBootstrap on a fast path by awaiting only fast services and detaching FileWatcher / Vcs init work

On my external-volume repro path, the first cold request dropped from about 6.3s to about 580ms.

How did you verify your code works?

  • added packages/opencode/test/project/bootstrap.test.ts for the detached bootstrap behavior
  • ran targeted tests for project, watcher, and bootstrap
  • ran the full packages/opencode test suite; remaining failures were pre-existing and unrelated
  • reproduced the cold-start path on /Volumes/DATA/github/TokenMeter

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. needs:issue labels Apr 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions github-actions Bot removed needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Apr 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

opencode and others added 8 commits April 20, 2026 07:21
Fall back to a deterministic path-based project ID when rev-list stalls so external-volume project open can recover without freezing the UI.
FileWatcher.init() blocks on parcel-watcher subscribe which can take
several seconds on external volumes (e.g. /Volumes/*).  With the
previous forkDetach approach, the child fiber blocked internally but
Effect's scheduler only ran it after the parent completed, meaning
the parent InstanceBootstrap was also delayed.

Fix: explicitly split InstanceBootstrap services into two groups:
- fastGroup (LSP, Format, File, Snapshot, ShareNext): awaited with
  concurrency=unbounded so handlers can safely use these services.
- deferredGroup (FileWatcher, Vcs): launched via forkDaemon so their
  blocking init() (subscribe, git branch/defaultBranch) runs in a
  daemon fiber and does not delay the HTTP response.

Closes: related to hanging on slow external-volume project open
…tests

- Replace forkDaemon/catchAllCause with forkDetach/catchCause to match
  Effect 4.0.0-beta.48's actual exported API (the patched local package
  does not export forkDaemon or catchAllCause).
- Add packages/opencode/test/project/bootstrap.test.ts with 5 tests:
  1. forkDetach does not block parent gen completion (< 500ms assertion)
  2. detached fiber failure does not propagate to parent
  3. concurrent init calls are guarded (init count == 1)
  4. bootstrap returns < 500ms with 2-second slow mock watcher
  5. bootstrap succeeds even when deferred service init throws
- Replace .map() over service union array with explicit Effect.all([...])
  calls for each service; union-typed .map() loses R/E type info and breaks
  callers that expect the typed AppLayer requirements (TS2345 on Effect<void,
  unknown, unknown> vs Effect<void, unknown, AppLayer>).
- Explicit forkDetach per service preserves the per-service R type correctly.
- Remove unused Cause import.
- Fix test mock: cast Effect.fail result to Effect<void> for the mock interface.
@codeg-dev codeg-dev force-pushed the fix/bootstrap-decouple-watcher-vcs branch from 6a6fe6d to 70ebe33 Compare April 20, 2026 11:01
@codeg-dev codeg-dev requested a review from adamdotdevin as a code owner April 20, 2026 11:01
@codeg-dev
Copy link
Copy Markdown
Author

Rebased onto v1.14.19 (2026-04-20). All 7 commits cherry-picked cleanly. Project bootstrap + MCP tests pass (33/33). The waitForThemeMode typecheck failure in app.tsx is a pre-existing issue in the release tag, not introduced by this PR.

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.

bug: cold project open hangs on external volumes during bootstrap

1 participant