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

Add Builder style APIs and docs for FlightData, FlightInfo, FlightEndpoint, Locaation and Ticket #4294

Merged
merged 4 commits into from
May 30, 2023

Conversation

alamb
Copy link
Contributor

@alamb alamb commented May 27, 2023

Which issue does this PR close?

Closes #4281

Rationale for this change

It is a PITA to create FlightInfo as described on #4281

As I was working on the code and examples, I realized it was a pain to create all the other types as well

What changes are included in this PR?

Add Builder style APIs and docs for FlightData, FlightInfo, FlightEndpoint, Locaation and Ticket

Since these are all prost generated stucts anyways all the fields are pub so I figured simply making it easier to modify them would be good

I changed the signatures of FlightInfo::new() and FlightData::new() as the existing functions are not very useful, which I will explain inline

@alamb alamb added the api-change Changes to the arrow API label May 27, 2023
@github-actions github-actions bot added arrow Changes to the arrow crate arrow-flight Changes to the arrow-flight crate labels May 27, 2023
@@ -222,26 +221,15 @@ impl FlightSqlService for FlightSqlServiceImpl {
ticket: Some(ticket),
location: vec![loc],
};
let endpoints = vec![endpoint];
let info = FlightInfo::new()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a pretty good example of the "before" and "after" that this PR provides.

It doesn't do anything different, it is just easier to work with the structures

let ticket = Ticket::new(query.encode_to_vec());
let endpoint = FlightEndpoint::new().with_ticket(ticket);

let flight_info = FlightInfo::new()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same thing here -- I claim this is a lot easier to read


/// Add a data body. See [`IpcDataGenerator`] to create this data.
///
/// [`IpcDataGenerator`]: arrow_ipc::writer::IpcDataGenerator
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Making a builder API gives a location to add some comments on what these fields should contain (the field description comes from the protobuf so is not Rust specific)

app_metadata: app_metadata.into(),
data_body: data_body.into(),
}
pub fn new() -> Self {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is technically a breaking change, but since all the fields on FlightData are pub anyways I don't think the old constructor was very useful (it was not used in the arrow codebase, for what that is worth)

@@ -433,24 +464,45 @@ impl FlightDescriptor {
}

impl FlightInfo {
/// Create a new [`FlightInfo`] that describes the access
/// coordinates for retrieval of a dataset.
pub fn new(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is also technically a breaking change, but since all the fields on FlightData are pub anyways I don't think the old constructor was very useful (as above)

/// encodes it using the default IPC options.
///
/// Returns an error if `schema` can not be encoded into IPC form.
pub fn with_schema(mut self, schema: &Schema) -> ArrowResult<Self> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was one of the nastiest APIs to deal with (figuring out the right incantation to encode the schema)

total_bytes: batch.get_array_memory_size() as i64,
ordered: false,
};
let info = FlightInfo::new()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again, I think the new version is much more readable (it is still fine to use the old syntax)

ordered: bool,
) -> Self {
let IpcMessage(vals) = message;
/// Create a new, empty `FlightInfo`, describing where to fetch flight data
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rather than making a new FlightInfoBuilder I eventually decided to just add the builder style methods on FlightInfo itself:

  1. It was simpler code
  2. I wasn't entirely sure what was valid / invalid semantically, so extra error checking seemed unecessary

@alamb alamb marked this pull request as ready for review May 29, 2023 11:07
@alamb
Copy link
Contributor Author

alamb commented May 29, 2023

cc @avantgardnerio and @roeap -- I wonder if you have time to review this PR?

Copy link
Contributor

@roeap roeap left a comment

Choose a reason for hiding this comment

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

Happy to, and looking great! Not only the figuring out he first time part is much better now, but this may also avoid some fairly repetitive code in downstream implementations.

Just one minor comment, that you may also choose to ignore :).

/// encodes it using the default IPC options.
///
/// Returns an error if `schema` can not be encoded into IPC form.
pub fn with_schema(mut self, schema: &Schema) -> ArrowResult<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just minor, but personally, I like to make the the fact that its fallible explicit in the name.

Suggested change
pub fn with_schema(mut self, schema: &Schema) -> ArrowResult<Self> {
pub fn try_with_schema(mut self, schema: &Schema) -> ArrowResult<Self> {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is a good idea -- I will make that change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in a6c973f

ordered: false,
// Flight says "Set these to -1 if unknown."
//
// https://github.com/apache/arrow-rs/blob/17ca4d51d0490f9c65f5adde144f677dbc8300e7/format/Flight.proto#L287-L289
Copy link
Contributor

Choose a reason for hiding this comment

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

Love this doc link, thank you for that

@alamb
Copy link
Contributor Author

alamb commented May 30, 2023

Thanks @roeap and @avantgardnerio

@alamb alamb merged commit 1b409a1 into apache:master May 30, 2023
@alamb alamb deleted the alamb/flight_info_builder2 branch May 30, 2023 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-change Changes to the arrow API 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.

Add Builder for FlightInfo to make it easier to create new requests
3 participants