Skip to content

Avoid duplicate provider startup probes#2777

Open
mjc wants to merge 5 commits into
pingdotgg:mainfrom
mjc:mjc/provider-startup-probing
Open

Avoid duplicate provider startup probes#2777
mjc wants to merge 5 commits into
pingdotgg:mainfrom
mjc:mjc/provider-startup-probing

Conversation

@mjc
Copy link
Copy Markdown

@mjc mjc commented May 21, 2026

Summary

Provider startup checks were being kicked off from two places:

  • makeManagedServerProvider started its own background boot probe when constructed
  • ProviderRegistryLive also subscribes to new provider instances and force-refreshes them during startup

That meant startup could run duplicate provider status checks for the same instance. This removes the older self-starting boot probe from managed providers and makes ProviderRegistryLive the single owner of startup refresh work.

Managed providers still refresh on explicit refresh, meaningful settings changes, and the periodic refresh interval.

Performance

Measured with:

bun scripts/bench-startup.js --project-count 100 --threads-per-project 100 --seed-mode projected --server-ready-only
bun scripts/bench-startup.js --project-count 100 --threads-per-project 100 --seed-mode projected

Against origin/main at d1e85c4e:

Scenario main this branch Change
Server ready, 3-run mean 10,392 ms 6,493 ms 3,899 ms faster, 37.5%
Server ready, median 10,137 ms 6,451 ms 3,685 ms faster
Full initial web sync total, 2-run mean 11,088 ms 7,271 ms 3,816 ms faster, 34.4%

Initial web sync itself stayed roughly flat, which is expected; the improvement is in server readiness.

Update

Added 1b6bbc1c as a follow-up to move provider refreshes off the startup readiness path. Context and benchmark comparison against #2728 are in this comment: #2777 (comment)

Tests

Added coverage that:

  • managed providers do not probe during construction
  • unchanged getSnapshot reads do not probe
  • explicit refresh still probes and streams updates
  • settings changes still re-probe
  • unchanged settings updates do not re-probe
  • periodic refresh still works
  • ProviderRegistryLive performs exactly one startup refresh for a managed provider

Verification

bun run --cwd apps/server test src/provider/makeManagedServerProvider.test.ts src/provider/Layers/ProviderRegistry.test.ts
bun fmt
bun lint
bun typecheck

Also launched the dev GUI in Chrome and verified it paired successfully and rendered the app shell on this branch.


Note

Low Risk
Test-only change that adjusts expectations around when the startup provider refresh runs; low risk aside from potentially masking a regression if the new timing assumptions are wrong.

Overview
Updates the ProviderRegistryLive startup-refresh test to assert that no provider probe happens during layer construction and that the initial snapshot remains visible until registry.startBackgroundRefreshes is invoked.

The test now waits for the background refresh to complete and verifies exactly one startup refresh call and that getProviders eventually reflects the refreshed snapshot.

Reviewed by Cursor Bugbot for commit 587d983. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Avoid duplicate provider startup probes by deferring background refreshes until server is ready

  • Managed providers no longer self-start an initial check on construction; the initial snapshot is returned until an explicit refresh(), settings change, or periodic timer fires.
  • ProviderRegistryLive no longer awaits provider checks during layer build or instance sync; it subscribes to change streams immediately and only starts refreshes when startBackgroundRefreshes is called.
  • Server startup now calls providerRegistry.startBackgroundRefreshes after the ready lifecycle event, forked in scope, so it does not block startup.
  • Adds a bench:startup script in scripts/bench-startup.js to measure server boot time under configurable database load.
  • Behavioral Change: callers that previously relied on an implicit initial provider probe at construction or registry sync will now see stale/initial snapshots until the server ready event fires.

Macroscope summarized 587d983.

Copilot AI review requested due to automatic review settings May 21, 2026 17:09
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 28d0e53d-394e-4847-9921-089951676a24

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels May 21, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new startup benchmarking script and adjusts managed provider startup behavior so that only the ProviderRegistry triggers the initial refresh, with updated tests to match.

Changes:

  • Introduces scripts/bench-startup.js to seed a large dataset, start the server, optionally measure initial web sync, and emit a JSON result payload.
  • Adds bench:startup / bench:pending-actions scripts to package.json.
  • Removes managed provider “probe on construction” behavior and updates/extends tests to ensure ProviderRegistry is the single startup refresh owner.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/bench-startup.js New CLI benchmark that seeds data, starts server, measures readiness/web sync, and reports metrics.
package.json Adds npm scripts to run the new benchmark (and pending-actions bench).
apps/server/src/provider/makeManagedServerProvider.ts Stops triggering an initial forced refresh during provider construction.
apps/server/src/provider/makeManagedServerProvider.test.ts Updates tests to reflect no probe on construction; adds coverage for explicit refresh and periodic refresh.
apps/server/src/provider/Layers/ProviderRegistry.test.ts Adds test ensuring ProviderRegistry performs exactly one startup refresh for managed instances.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/bench-startup.js Outdated
Comment thread scripts/bench-startup.js
Comment thread scripts/bench-startup.js Outdated
Comment thread scripts/bench-startup.js Outdated
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 21, 2026

Approvability

Verdict: Needs human review

This PR modifies server startup behavior by deferring provider probes until after server readiness, changing initialization timing and when provider state becomes available. Changes to startup/initialization lifecycle ordering warrant human review to validate the intended behavior across different scenarios.

You can customize Macroscope's approvability policy. Learn more.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9246bde9ec

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package.json Outdated
@mjc
Copy link
Copy Markdown
Author

mjc commented May 21, 2026

realized I should make the script a separate commit so I'm gonna do that too.

@mjc mjc force-pushed the mjc/provider-startup-probing branch from 9246bde to f48b553 Compare May 21, 2026 17:21
Comment thread package.json
@mjc mjc force-pushed the mjc/provider-startup-probing branch from f48b553 to d85ef38 Compare May 21, 2026 17:23
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes May 21, 2026
Move provider CLI status checks out of provider layer construction and start them from ServerRuntimeStartup only after the server has printed ready access information. ProviderRegistry now exposes an explicit startBackgroundRefreshes hook; manual refresh paths still work before startup readiness, and rebuilt instances refresh immediately once background refreshes are enabled.

Benchmarks (100 projects x 100 threads, projected seed, server-ready-only):

| ref | seed ms | serverReady ms | top ready-path evidence |

| --- | ---: | ---: | --- |

| server-ready-delete-boot-refresh-10k | n/a | 4357.344 | OpenCode provider check still dominated startup |

| server-ready-provider-refresh-async-10k | 2962.655 | 4609.096 | provider refresh was forked but still contended before ready output |

| server-ready-provider-refresh-after-output-10k | 3004.054 | 2725.643 | provider spans only show in post-ready stop trace; ready output is no longer behind CLI probes |

Verification: nix develop "git+file:///Users/mjc/projects/t3code?ref=daily-use" -c bun fmt; bun lint; bun typecheck; bun run test.
@mjc
Copy link
Copy Markdown
Author

mjc commented May 21, 2026

I noticed #2728 is addressing the same startup bottleneck: provider probing is on the server readiness path.

I tried a slightly different version of that idea in 1b6bbc1c. Instead of adding a new pending provider state and forking the initial registry sync directly, it keeps the existing provider contract and adds an explicit lifecycle hook: ProviderRegistry.startBackgroundRefreshes. Startup calls that only after command readiness, HTTP readiness, the ready lifecycle event, and startup output/browser open. Manual refresh / refreshInstance still work before then.

Measured with the same server-ready-only startup benchmark:

Fixture: synthetic home with 100 projects x 100 threads, 10,000 threads total, 0 activities/thread, projected seed. 5 measured runs.

branch commit median mean
main d1e85c4e 10334.726 ms 10315.633 ms
#2728 f4d3212d 4984.263 ms 4853.764 ms
this approach 1b6bbc1c 3125.904 ms 3081.513 ms

So #2728 is a real improvement, but this approach is another 1858.359 ms faster by median versus #2728 in this benchmark, and avoids expanding the shared provider state contract.

I’m going to add this commit to this PR as the follow-up version of the same fix.

@macroscopeapp macroscopeapp Bot dismissed their stale review May 21, 2026 22:40

Dismissing prior approval to re-evaluate 1b6bbc1

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1b6bbc1. Configure here.

Comment thread apps/server/src/provider/Layers/ProviderRegistry.test.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants