Server: a notifications/cancelled that arrives before the request's handler task is registered is dropped, so the request runs to completion
I maintainer di solito rispondono entro 7 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
Start with Sources/MCP/Server/Server.swift at the receive-loop dispatch, handleRequest, and removePendingRequest(id:) locations described in the issue. Review PR #270 and its “Cancellation received before handler registration prevents handler start” barrier test; done means the reproduction no longer starts or responds to a request cancelled immediately after dispatch.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Server registers a request's handler task for cancellation after it has already returned to the receive loop, so a notifications/cancelled that follows the request closely enough is processed before the registration exists. The cancellation is then logged as "unknown or completed" and ignored, and the request runs to completion and sends its response — for a request the server has, in fact, received and is about to start.
Mechanics (0.12.1, Sources/MCP/Server/Server.swift)
- The receive loop decodes a request and hands it off without waiting (
:235):
The loop immediately continues to the next stream element.} else if let request = try? decoder.decode(AnyRequest.self, from: data) { // Handle request in a separate task to avoid blocking the receive loop Task { _ = try? await self.handleRequest(request, sendResponse: true) } } - Inside that task,
handleRequestfirst awaits the transport's HTTP context lookup (:784) and only then registers the task (:816):pendingRequestTasks[request.id] = handlerTask - Meanwhile the loop has already decoded the next element. If it is
notifications/cancelledfor that id, the built-in handler runsremovePendingRequest(id:)(:1001), finds nothing, and takes the "unknown or completed" branch. Nothing cancels the handler task once it is registered a moment later.
The window is the gap between the detached Task at :235 and the assignment at :816, which includes an await. It is a real ordering hazard, not a theoretical one: any client that sends a request and cancels it immediately (a user abort, a timeout that fires during send) can hit it, and it is deterministic to reproduce with a barrier that holds the context lookup until the cancellation has been consumed.
Expected behavior
The cancellation spec says the receiver SHOULD stop processing the cancelled request and not send a response, and MAY ignore a cancellation for an unknown request. This request is not unknown — the server decoded it and dispatched it — so ignoring the cancellation is a missed SHOULD caused by an implementation race, not a legitimate "unknown request" case. A cancellation that arrives after dispatch and before registration should still cancel the request, or prevent the handler from starting.
Reproduction
On any transport (stdio, or two back-to-back stateless HTTP POSTs), send:
{"jsonrpc":"2.0","id":"r1","method":"tools/call","params":{"name":"slow"}}- immediately:
{"jsonrpc":"2.0","method":"notifications/cancelled","params":{"requestId":"r1"}}
Observe: the slow handler runs and a response for r1 is sent. With a transport whose httpRequestContext(for:) is held until after the cancellation is consumed, the outcome is deterministic.
Existing fix
PR #270 (Fix early request cancellation race) addresses exactly this: it tracks the dispatch task before handler registration so an immediate cancellation cannot fall through the gap, processes the built-in cancellation handler before other notification handlers can suspend, and adds a deterministic barrier test (Cancellation received before handler registration prevents handler start). That PR currently references no issue; this one is filed so the defect has a tracking entry independent of any particular fix. #270 also carries two adjacent hardening changes — suppressing a late response from a handler that swallows CancellationError, and rejecting duplicate outstanding request ids in Server — which are worth noting when reviewing it, since the second is a behavior change beyond this bug.
Related
- #255 — a cancelled request's HTTP POST hangs in
StatelessHTTPServerTransport(the transport side of cancellation; fix in #260) - #254 / #265 — colliding JSON-RPC ids across concurrent stateless clients (fix in #264); with exchange-scoped ids in place,
Server's duplicate-id rejection from #270 only ever triggers on single-client transports
- Lingua principale
- Swift
- Stelle
- 1.5k
- Fork
- 252
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di modelcontextprotocol/swift-sdk
-
NetworkTransport leaks the underlying socket (CLOSE_WAIT) when reconnection is disabled and the receive loop terminatesForse già presa @skirrellyjones l’ha presa 34 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
modelcontextprotocol/swift-sdk#282 ·
I maintainer di solito rispondono entro 7 giorni
-
Value decoding changes data-URL-looking JSON strings into Value.dataForse già presa @bitbemol l’ha presa 45 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
modelcontextprotocol/swift-sdk#277 ·
I maintainer di solito rispondono entro 7 giorni
-
enhancement
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
modelcontextprotocol/swift-sdk#274 ·
I maintainer di solito rispondono entro 7 giorni
-
`HTTPClientTransport` fails to build on Windows: `#if !os(Linux)` guards no longer match the `EventSource` platform conditionForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
modelcontextprotocol/swift-sdk#261 ·
I maintainer di solito rispondono entro 7 giorni
-
Value: add numberValue (Double?) that coerces .int and .doubleForse già presa @gsdali l’ha presa 156 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
modelcontextprotocol/swift-sdk#225 ·
I maintainer di solito rispondono entro 7 giorni
Tutte le issue di modelcontextprotocol/swift-sdk
Issue simili
-
iOS: recorded video location is written without ISO 6709 fixed-width degrees, Photos drops itAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
margelo/react-native-vision-camera#4216 ·
I maintainer di solito rispondono entro 4 giorni
-
documentation good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
compiler-explorer/compiler-explorer#9272 ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature] 建议出下卸载方法Apertaenhancement
Difficoltà 1/5 1-3 ore Idoneità per principianti 66/100
I maintainer di solito rispondono entro 1 giorno
-
P2 package platform-ios team-ios
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno