Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

`Client.connect` busy-loops at 100% CPU when the transport reaches EOF before `initialize` completes

Aperta
#256 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

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
72/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
swift

Direzione di ricerca

Start in Sources/MCP/Client/Client.swift at the message-handling task created by Client.connect and inspect how connection.receive() behaves when its AsyncThrowingStream finishes. Run the described /usr/bin/true StdioTransport reproduction first. Done means EOF stops further receive polling and connect/_initialize throws a connection-closed error instead of hanging.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

If a spawned MCP server dies (or closes its stdout) during startup — before the client's initialize handshake finishes — Client.connect(transport:) never returns and one core sits pinned at 100%.

What I see: a stdio server that exits immediately on launch. ps shows the host process in state R, and sample <pid> shows the spin inside closure #1 in Client.connect → AsyncThrowingStream.Iterator.next().

The message-handling loop in Sources/MCP/Client/Client.swift is (trimmed):

task = Task {
    guard let connection = self.connection else { return }
    repeat {
        if Task.isCancelled { break }
        do {
            let stream = await connection.receive()
            for try await data in stream {
                if Task.isCancelled { break }
                // decode + dispatch
            }
        } catch { break }
    } while true
}
// ...
return try await _initialize()

When the transport hits EOF, the stream from receive() finishes, the for try await completes without throwing, and while true immediately loops back and calls receive() again, which returns another already-finished stream. Nothing sleeps or exits on end-of-stream, so it spins. Meanwhile connect has moved on to await _initialize(), whose response never arrives because the server is gone, so connect is parked forever on a continuation nothing resumes.

Minimal repro: spawn /usr/bin/true via Process with two Pipes, wrap the pipe fds in a StdioTransport(input:output:), build a Client, and try await client.connect(transport:). Just re-ran this against v0.12.1: connect has neither returned nor thrown 8 seconds in, and ps samples the process at ~100% CPU for the whole wait (96.6 / 100.0 / 100.0 / 100.0 over four 1.5s samples).

Two changes would fix it:

  • The loop should stop (or back off) when the underlying stream finishes rather than re-polling a finished stream — a finished transport stream means the connection is gone.
  • connect / _initialize should then fail with a connection-closed error instead of hanging.

For what it's worth, my workaround is to race connect against a timeout and call client.disconnect() on expiry — disconnect() cancels that task and resumes the pending initialize with an error, so connect throws instead of hanging. Separately I had to set signal(SIGPIPE, SIG_IGN), because writing to the dead server's stdin was raising SIGPIPE and taking down the whole host process. I'd be happy to turn the loop-termination part into a PR if that's welcome.

Lingua principale
Swift
Stelle
1.5k
Fork
252
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di modelcontextprotocol/swift-sdk

Tutte le issue di modelcontextprotocol/swift-sdk

Issue simili

Altre issue su Swift

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.