Skip to content

fix(vmcp): bound initialize to healthCheckTimeout - #6380

Open
RaviTharuma wants to merge 4 commits into
stacklok:mainfrom
RaviTharuma:fix/vmcp-bound-initialize
Open

fix(vmcp): bound initialize to healthCheckTimeout#6380
RaviTharuma wants to merge 4 commits into
stacklok:mainfrom
RaviTharuma:fix/vmcp-bound-initialize

Conversation

@RaviTharuma

@RaviTharuma RaviTharuma commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Cross-links

Summary

VirtualMCPServer Ready and GET /health could stay OK while a new client's
initialize hung past typical gateway timeouts (12s) with a 0-byte response.

Those signals are different operations: /health is liveness, Ready is the
last ListCapabilities probe, and initialize waits on backend handshakes
(per-backend 30s, concurrency 10). This does not flip Ready//health on
initialize failure (that would flap). It bounds the handshake.

  • Overall MakeSession budget defaults to 10s (same as CRD
    healthCheckTimeout)
  • Wire WithSessionInitTimeout from failureHandling.healthCheckTimeout
    when set
  • Unfinished backends are skipped (best-effort session), not a hard error
  • Document Health vs Ready vs initialize

Fixes #6345

Type of change

  • Bug fix
  • New feature
  • Refactoring (no behavior change)
  • Dependency update
  • Documentation
  • Other (describe):

Test plan

  • go test -ldflags=-extldflags=-Wl,-w ./pkg/vmcp/session/ -run 'TestWithSessionInitTimeout|TestNewSessionFactory_SessionInitTimeout|TestNewSessionFactory_BackendInitTimeout|TestNewSessionFactory_AllBackendsFail'
  • CI unit tests
  • After merge: a slow backend must not hold initialize past
    healthCheckTimeout; /health remains liveness-only

API Compatibility

This does not change the CRD schema. healthCheckTimeout already exists; it
now also bounds session initialize.

Does this introduce a user-facing change?

Yes. New vMCP sessions finish initialize within healthCheckTimeout
(default 10s). Slow backends are omitted from that session instead of
blocking the client. /health is documented as liveness only.

Special notes for reviewers

Direction from #6345: Ready is ListCapabilities, initialize is a different
handshake. Bounding + documenting is the agreed path; a separate SessionReady
signal is left for a follow-up if you want it.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@RaviTharuma

Copy link
Copy Markdown
Contributor Author

Implements #6345 per maintainer direction.

Cross-links:

@RaviTharuma

Copy link
Copy Markdown
Contributor Author

Automated fix: rebased onto main (20 commits). Remaining golangci findings are in operator files this PR does not touch (gci/staticcheck SA1019).

@RaviTharuma
RaviTharuma force-pushed the fix/vmcp-bound-initialize branch from 72f5609 to 880e09d Compare August 20, 2026 16:41
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.30%. Comparing base (fd1e7b5) to head (02a515e).

Files with missing lines Patch % Lines
pkg/vmcp/cli/serve.go 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6380      +/-   ##
==========================================
- Coverage   78.31%   78.30%   -0.02%     
==========================================
  Files         770      770              
  Lines       75456    75479      +23     
==========================================
+ Hits        59095    59104       +9     
- Misses      16356    16370      +14     
  Partials        5        5              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cursor
cursor Bot force-pushed the fix/vmcp-bound-initialize branch from e14a014 to cdf9562 Compare August 30, 2026 09:53
Copilot AI lite review requested due to automatic review settings September 2, 2026 10:21
@cursor
cursor Bot force-pushed the fix/vmcp-bound-initialize branch from cdf9562 to 6f61794 Compare September 2, 2026 10:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to prevent vMCP client-facing initialize from hanging past typical gateway/client timeouts while /health and the VirtualMCPServer Ready signal remain green, by introducing an overall session initialization budget tied to healthCheckTimeout and documenting the distinction between liveness, readiness, and session init.

Changes:

  • Add an overall sessionInitTimeout budget to the vMCP session factory to bound MakeSession initialization time (best-effort: slow backends are skipped).
  • Wire failureHandling.healthCheckTimeout into the session factory as the initialize budget (default remains 10s).
  • Document Health vs Ready vs initialize, and propagate updated field descriptions into generated/operator docs and CRDs.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/vmcp/session/factory.go Introduces default session init budget + option, applies timeout context, and logs when budget expires.
pkg/vmcp/session/default_session_test.go Adds unit tests for the new session init timeout option and bounding behavior.
pkg/vmcp/server/server.go Clarifies /health as liveness-only and distinguishes it from readiness/session init.
pkg/vmcp/config/config.go Documents that healthCheckTimeout also bounds client session initialize across backends.
pkg/vmcp/cli/serve.go Plumbs failureHandling.healthCheckTimeout into WithSessionInitTimeout.
docs/operator/virtualmcpserver-api.md Adds operator-facing documentation on Health vs Ready vs initialize semantics.
docs/operator/crd-api.md Updates CRD API docs to reflect the expanded meaning of healthCheckTimeout.
deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml Updates chart CRD template descriptions for healthCheckTimeout.
deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml Updates packaged CRD descriptions for healthCheckTimeout.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/vmcp/session/factory.go
Comment thread pkg/vmcp/session/factory.go
RaviTharuma and others added 4 commits September 3, 2026 23:27
A new session waited on every backend's 30s init timeout, so initialize
could hang past gateway limits while Ready and /health stayed OK. Cap
MakeSession to healthCheckTimeout (default 10s) and document the three
signals.

Fixes stacklok#6345
Signed-off-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com>
Queued backend init must not block on the semaphore after the
session budget expires. Warn only on deadline exceeded; log
caller cancel at debug.

Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com>
@RaviTharuma
RaviTharuma force-pushed the fix/vmcp-bound-initialize branch from 191387a to 02a515e Compare September 3, 2026 23:30
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(vmcp): Ready and /health stay OK while initialize can hang past client timeouts

3 participants