grpc-js v1.14.0: Unary calls stop transmitting after several hours — only HTTP/2 ping/pong visible, no new RPCs leave the client
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Da chiarire
- Stato di attività
- Ferma
- Stack tecnologico
- node.js, typescript
- Ambito
- backend-api-design, networking
Direzione di ricerca
Riproduci il pattern di uptime di 3–5 ore con i due stream persistenti e le chiamate periodiche a Subscribe, utilizzando i log di debug gRPC e le evidenze di tcpdump descritte nell’issue. Traccia il subchannel READY e la Http2Session dopo lo stallo; il lavoro è completato quando le nuove chiamate unary generano traffico HTTP/2 in uscita oppure la connessione non funzionante viene rilevata e ripristinata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem description
After several hours of uptime, all new unary gRPC calls (Subscribe) from our Node client stop transmitting over TCP.
At the application layer, client.Subscribe() appears to execute normally and logs “write called,” but when inspecting with tcpdump, no new TCP traffic is sent — only the periodic gRPC HTTP/2 ping/pong frames.
Restarting the Node process or explicitly closing and recreating the client fixes it immediately (new TCP SYN, new subchannel, traffic resumes).
This strongly suggests the internal HTTP/2 subchannel or transport remains “READY” but is stuck / non-functional — effectively a ghost connection.
Environment
Library: @grpc/grpc-js
Version: 1.14.0
Node.js: v20.x
OS: Rocky Linux 9
Connection: direct TCP (no proxy / load balancer)
Server: C++ gRPC v1.62.0
RPCs used:
Unary: Subscribe, Unsubscribe
Server streaming: MvrStream, BckPypStream (always open)
Reproduction steps
Reproduction pattern
Start client and server.
Client opens two persistent streaming RPCs (MvrStream, BckPypStream) and periodically issues unary RPCs Subscribe(account_id, study_type) every few minutes.
Everything works fine for a few hours.
After several hours of uptime (typically 3–5h), all new Subscribe calls silently hang — no callback, no error.
Verbose gRPC logs still show write() called, halfClose called.
tcpdump shows only small 17-byte packets every 5s (keepalive ping/pong). No new HEADERS/DATA frames leave the client.
Restarting the client (new channel) immediately restores functionality.
Expected behavior
When client.Subscribe() is called, gRPC should open a new HTTP/2 stream and send the unary request.
Actual behavior
The call remains pending indefinitely.
No outbound network traffic occurs (only keepalive).
Channel state remains READY — no reconnects triggered.
Manual client.close() + recreate fixes it instantly.
tcpdump evidence
(Port 50051; 10.18.35.30 = server)
Only ping/pong frames observed:
05:11:25.084 IP 10.18.35.20.52840 > 10.18.35.30.50051: Flags [P.], seq 620:637, ack 264, win 125, length 17
05:11:25.085 IP 10.18.35.30.50051 > 10.18.35.20.52840: Flags [P.], seq 264:281, ack 637, win 501, length 17
No new TCP frames (DATA/HEADERS) appear when Subscribe() is invoked.
gRPC debug logs around the stall
D | resolving_call | [76330] write() called with message of length 11
D | resolving_call | [76330] halfClose called
D | load_balancing_call | [76333] Pick result: COMPLETE subchannel: (2) 10.18.35.30:50051 status: undefined undefined
D | subchannel_call | [9] sending data chunk of length 11
after hours...
D | resolving_call | [0] write() called with message of length 16
but no subchannel_call send or receive
After this point, pings continue, but no new outbound streams appear.
Analysis
It looks like the subchannel’s Http2Session remains open and ping/pong-responsive, but stops issuing new stream IDs.
grpc-js continues to route new calls to this “READY” subchannel, which never transmits.
This is effectively a zombie subchannel:
TCP connection alive (ping ACKs).
gRPC channel stuck in READY.
New calls never written to the wire.
- Lingua principale
- TypeScript
- Stelle
- 4.8k
- Fork
- 716
- Merge medio
- 1g 18h
- PR unite (30g)
- 17
Preparare l'ambiente
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 grpc/grpc-node
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 2 giorni
-
package: @grpc/grpc-js
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
grpc/grpc-node#2993 · 3 commenti · 4 reazioni ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 65/100
grpc/grpc-node#3091 · 1 reazione ·
I maintainer di solito rispondono entro 2 giorni
-
feature request
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
grpc/grpc-node#3077 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 76/100
grpc/grpc-node#3068 · 2 commenti · 1 reazione ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di grpc/grpc-node
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
openedx/frontend-app-authoring#3274 ·
I maintainer di solito rispondono entro 1 giorno
-
🎙️ task - fix(deployer): deploy --env prep runs deploy:dev where the repo declares deploy:prepAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
-
area/documentation status/need-triage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 95/100
google-gemini/gemini-cli#29548 ·
I maintainer di solito rispondono entro 1 giorno
-
sdk-typescript vector-store
Difficoltà 2/5 Mezza giornata Idoneità per principianti 82/100
mem0ai/mem0#7495 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno