Skip to content

fix(server): answer MCP initialize before startup warm-up - #49

Merged
JRedeker merged 1 commit into
mainfrom
work/work-94e47dd3cef330141dcb08e3
Oct 24, 2026
Merged

JRedeker merged 1 commit into
mainfrom
work/work-94e47dd3cef330141dcb08e3

Conversation

@JRedeker

Copy link
Copy Markdown
Contributor

Problem

Since 06:32 EDT every Vision respawn of lgrep fails: end-to-end initialize: context deadline exceeded, then shared_session.spawn_failed error="context canceled" 10 s after spawn. app_lifespan awaited _warm_projects before yielding, so initialize waited for every warm path's store open. With Vision's five warm paths a direct stdio probe answered initialize after 9.99 s; the concord store open alone took 6.6 s (uncompacted versions, LGREP-36).

A second startup defect, from #48: cap_malloc_arenas() logged before configure_logging(), so its event went through structlog's default printer to stdout, the stdio MCP channel.

Change

  • app_lifespan runs warm-up as a background task, cancelled and awaited at shutdown with the startup sweep.
  • run_server configures logging before capping arenas.

Evidence

  • tests/test_server.py::TestLifecycle::test_lifespan_yields_before_warm_and_cancels_it_at_shutdown and tests/test_bootstrap.py::...::test_run_server_writes_nothing_to_stdout_before_serving each fail without their fix.
  • Full suite: 1238 passed, 1 skipped (no distribution metadata under PYTHONPATH), 1 xfailed; ruff clean.
  • Same stdio probe with Vision's env: initialize answered in 2.45 s, first stdout line is JSON-RPC, warm-up completed in the background, clean exit.

app_lifespan awaited _warm_projects before yielding, so the server
answered no request, initialize included, until every warm path had
opened its store. With five warm paths and an uncompacted concord
table, initialize took 9.99 s and Vision abandoned each spawn at its
10 s connect deadline. Warm-up now runs as a background task that the
lifespan cancels and awaits at shutdown, alongside the startup sweep.

run_server also configures logging before capping malloc arenas: the
cap's startup event otherwise went through structlog's default printer
to stdout, the stdio MCP channel.
@JRedeker
JRedeker enabled auto-merge (squash) October 24, 2026 17:08
@JRedeker
JRedeker merged commit d57e7d3 into main Oct 24, 2026
4 checks passed
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.

1 participant