Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose DoGet response headers & trailers #4727

Merged

Conversation

crepererum
Copy link
Contributor

Which issue does this PR close?

-

Rationale for this change

HTTP/2 headers can already be sent by the client (and trivially by the server as part of the tonic::Response object). However the the client doesn't expose the response headers yet. They can include debug information like server version or other metadata.

Trailers are less commonly used but can include information that is only available AFTER the response stream finishes, e.g. "number of scanned files", "total rows read from files", etc. Tonic doesn't have a super nice way to write them from the server side, but a tower layer makes that possible. Also we have to consider non-Rust implementations that can make use of trailers.

People that read the HTTP/2 spec may wonder how headers and trailers are encoded in a stream scenario. Turns out that they have their own HEADERS message. The first HEADERS message transmit the HTTP headers, the last one at the stream end (w/ the END_STREAM flag set) the trailers. Now you may wonder if you could send headers mid-stream as well. Now the HTTP/2 spec doesn't seem to disallow that, but:

  • neither tonic and tower have a way to do that

  • this stackoverflow answer suggests that this is not allowed because HTTP itself has no semantic for that and indeed the HTTP/2 spec say:

    This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP's existing semantics remain unchanged.

    This is also confirmed by this stackoverflow answer.

So I think metadata can only be sent at the beginning and at the end of a stream. Everything else would also be a bit of an API mess.

What changes are included in this PR?

Wires HTTP/2 headers and trailers into flight client DoGet method. Tests included.

Are there any user-facing changes?

New methods to get headers and trailers.

@github-actions github-actions bot added arrow Changes to the arrow crate arrow-flight Changes to the arrow-flight crate labels Aug 23, 2023
Comment on lines +70 to +72
http = "0.2.9"
http-body = "0.4.5"
pin-project-lite = "0.2"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not really new dependencies, they are already used by tonic & tower, but I need to name the types.

@crepererum
Copy link
Contributor Author

I can extend this to other client methods in follow-up PRs if this gets accepted.

@crepererum crepererum force-pushed the crepererum/flight_get_header_trailer branch 2 times, most recently from e8cd55c to 852651e Compare August 23, 2023 13:59
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is both very cool and very nicely coded @crepererum -- thank you and well done ❤️

I had some small naming / comment suggestions, but otherwise 🚀

arrow-flight/src/decode.rs Outdated Show resolved Hide resolved
arrow-flight/src/trailers.rs Outdated Show resolved Hide resolved
arrow-flight/tests/client.rs Show resolved Hide resolved
@@ -204,16 +204,14 @@ impl FlightClient {
pub async fn do_get(&mut self, ticket: Ticket) -> Result<FlightRecordBatchStream> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other methods on this client that might be interested in server headers/trailers -- like do_exchange and do_put. Maybe we can file a ticket to track adding support for them too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crepererum crepererum force-pushed the crepererum/flight_get_header_trailer branch 2 times, most recently from a239401 to 147ff80 Compare August 25, 2023 08:09
crepererum and others added 2 commits August 25, 2023 10:59
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
@crepererum crepererum force-pushed the crepererum/flight_get_header_trailer branch from 147ff80 to 74ed1df Compare August 25, 2023 08:59
@crepererum crepererum force-pushed the crepererum/flight_get_header_trailer branch from 74ed1df to 8adf5e3 Compare August 25, 2023 09:27
@crepererum crepererum merged commit 4533271 into apache:master Aug 25, 2023

/// Extract [`LazyTrailers`] from [`Streaming`] [tonic] response.
///
/// Note that [`LazyTrailers`] has inner mutability and will only hold actual data after [`ExtractTrailersStream`] is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrow Changes to the arrow crate arrow-flight Changes to the arrow-flight crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants