tonic
tonic copied to clipboard
Sending data frame followed by trailer frame discards the data frame
Version
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] }
tokio-rustls = { version = "0.26.0", default-features = false, features = ["ring"] }
tokio-stream = "0.1.15"
tonic = { version = "0.11.0", features = ["tls"] }
Platform
Linux DESKTOP-NS87UGU 5.15.146.1-microsoft-standard-WSL2 #1 SMP x86_64 x86_64 x86_64 GNU/Linux
Description
I use tokio with a full-duplex streaming gRPC server (using tonic).
I've opened the issue here, since the Sender
struct is created from tokio::sync::mspc
, but if this issue needs to be ported to tonic, please let me know.
When the server sends a data frame, followed by a trailer (header with END_STREAM) frame, the data frame is discarded. If I wait for some duration between the two sends, the data frame is not discarded.
Code sample:
async fn stream_responses(tx: &Sender<Result<MyStruct, Status>>) {
tx.send(Ok(MyStruct {})).await.expect("failure");
// Uncomment the following line so the data packet sent above is not discarded.
// tokio::time::sleep(std::time::Duration::from_nanos(1)).await;
tx.send(Err(Status::aborted("message"))).await.expect("failure");
}
In the code above (simplified to the relevant parts, I first send a Ok
message, which is expected to be sent as an HTTP/2 DATA frame. Then I send an Err
message, which is expected to be sent as an HTTP/2 HEADER frame with END_STREAM
flag.
I am using Wireshark to inspect the wire data and see what messages are actually being transported.
I expect both these frames to be sent. However, the data frame is discarded, and I only see HEADERS
frame:
When I add a small delay between both sends (uncomment the comment in the code example above), I see both frames successfully sent, as expected: