Skip to content

fix(upstream): make the late-callback test deterministic under CI load - #1692

Merged
Dumbris merged 2 commits into
mainfrom
fix/late-callbacks-flake
Oct 20, 2026
Merged

Dumbris merged 2 commits into
mainfrom
fix/late-callbacks-flake

Conversation

@Dumbris

@Dumbris Dumbris commented Oct 20, 2026

Copy link
Copy Markdown
Member

Summary

TestManager_LateCallbacks_ReachExistingClients (added by #1586) has timed out on every PR Build run since it merged and today started failing the required Unit Tests (ubuntu-latest, 1.26) and Unit Tests (shuffle) jobs as well, on PRs that cannot have caused it (for example the docs-only #1688: PR Build, Unit Tests).

Cause. In github.com/mark3labs/mcp-go@v1.0.0 server/streamable_http.go (handlePost), in-request notifications are forwarded to the SSE response by a goroutine. When the tool handler returns, the request goroutine takes the stream mutex, drains what is still queued, and closes done; the forwarder, which had already dequeued one notification and was waiting on that mutex, then hits the non-resumable case <-done: return and discards it. So exactly one of the notifications a call sends can be lost, and which one depends on scheduling. The test's single warmup notification absorbs the loss only when the forwarder happens to be holding the warmup; on a loaded runner it is the tools or prompts notification often enough to fail every run.

Reproduction. 2×ncpu busy loops (yes > /dev/null) alongside the test: 9 of 20 runs failed on main.

Fix (test only). The call to the notify tool is repeated until both late-registered callbacks have fired (500 ms settle per attempt, 10 s deadline), and the callbacks are non-blocking signals so a repeated call can never block core's notification goroutine. The property the test guards is unchanged: callbacks registered after the client exists must be invoked on tools/list_changed and prompts/list_changed; a plumbing regression still fails after the deadline with a message naming which callback never fired.

Verification. Under the same contention: 25/25 plain, 20/20 with -race. go test -race ./internal/upstream/... green. golangci-lint v2 (.github/.golangci.yml, bare and --build-tags server) clean on the changed file.

Related #1586

🤖 Generated with Claude Code

Dumbris and others added 2 commits October 20, 2026 14:37
Related #1586

TestManager_LateCallbacks_ReachExistingClients timed out on every PR Build
run since it merged, and today on the required Unit Tests job too. The
cause is in mcp-go v1.0.0's streamable-HTTP server: in-request
notifications are forwarded to the SSE response by a goroutine, and when
the tool handler returns the request goroutine takes the stream mutex,
drains the queue and closes done, so the forwarder discards the one
notification it had already dequeued. Which of the three notifications is
lost depends on scheduling, so the single warmup did not cover it; under
CPU contention (2x ncpu busy loops) the test failed 9 of 20 runs locally.

The test now repeats the notify call until both late-registered callbacks
have fired (500 ms settle per attempt, 10 s deadline) and the callbacks
are non-blocking signals so a repeat can never block core's notification
goroutine. Under the same contention it passed 25/25 plain and 20/20 with
-race.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ck test

A forwarder left over from an earlier request can discard a later call's
notification as well, so the comment no longer claims a fixed minimum per
attempt (opencode Sol 6.1 review, low).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2101716
Status: ✅  Deploy successful!
Preview URL: https://d4160ac7.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-late-callbacks-flake.mcpproxy-docs.pages.dev

View logs

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/late-callbacks-flake

Available Artifacts

  • archive-darwin-amd64 (32 MB)
  • archive-darwin-arm64 (28 MB)
  • archive-linux-amd64 (19 MB)
  • archive-linux-arm64 (17 MB)
  • archive-windows-amd64 (31 MB)
  • archive-windows-arm64 (28 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (27 MB)
  • installer-dmg-darwin-arm64 (25 MB)
  • smart-mcp-proxymcpproxy-goHVWIGR.dockerbuild (0 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 39416617955 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Dumbris
Dumbris merged commit 3558c53 into main Oct 20, 2026
47 checks passed
@Dumbris
Dumbris deleted the fix/late-callbacks-flake branch October 20, 2026 14:01
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.

2 participants