Single onNext() on a server-streaming call is not flushed to the wire until a second write or stream close happens #12902
Replies: 1 comment
|
A genuine server-streaming descriptor should not wait for a second write in 1.72.0. That makes the runtime method type the first thing to check: System.out.println(
TransferServiceGrpc.getGetTransferStatusMethod().getType());For the method you described, this must print: and the proto declaration must contain rpc GetTransferStatus(TransferStatusRequest)
returns (stream TransferStatusResponse);If the descriptor prints The likely causes are stale generated There is no supported |
Uh oh!
There was an error while loading. Please reload this page.
I'm seeing gRPC-Java (grpc-netty-shaded 1.72.0) not flush a DATA frame to the
socket for a server-streaming RPC when the handler calls onNext() exactly
once and never calls onNext() again or onCompleted()/onError() afterward.
Repro:
@OverRide
public void getTransferStatus(TransferStatusRequest request,
StreamObserver responseObserver) {
responseObserver.onNext(TransferStatusResponse.newBuilder()
.setStatus("Update 0 time: " + LocalDateTime.now())
.build());
// deliberately nothing else called — no onCompleted(), no more onNext()
}
Verified with two independent clients (grpcurl and Postman) — neither
receives the message. If I later add a second onNext() (even minutes
later via a separate ScheduledExecutorService thread) or call
onCompleted(), the FIRST message is delivered at that point, not when
onNext() was originally called — both timestamps show up on the client
close together.
Ruled out so far:
happens instantly on the original call thread, no sleep before it,
and it's still withheld.
happens even if onCompleted() is never called; ANY second event on
the stream flushes the backlog.
Question: What is the actual trigger gRPC-Java/Netty uses to flush a
pending onNext() write for a server-streaming call — is there a
write-coalescing/batching mechanism (e.g. tied to WriteQueue,
periodic flush, or channel writability) that withholds a single queued
message until a second write event occurs? Is there a supported way
(e.g. via ServerCallStreamObserver, channel options, or a builder flag)
to force an immediate flush after a single onNext() with no further
activity?
Setup: Spring-less plain ServerBuilder.forPort(...), grpc-netty-shaded
1.72.0, Java 21, Windows, plaintext (no TLS).
All reactions