hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
9.35k stars 957 forks source link

Sending data frame followed by trailer frame discards the data frame #1717

Open ohadvano opened 1 month ago

ohadvano commented 1 month ago

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: image

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:

image