Sending data frame followed by trailer frame discards the data frame
- Dominant language
- Rust
- Stars
- 12.5k
- Forks
- 1.3k
- Avg merge
- 4d 7h
- Merged PRs (30d)
- 24
Description
**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>) {
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:

Contributor guide
Assessment
This issue has not been assessed yet.