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

Fix dropshot-pagination _stream client codegen #756

Merged
merged 3 commits into from
Apr 3, 2024
Merged

Conversation

jgallagher
Copy link
Contributor

Closes #755; see it for details!

@jgallagher jgallagher requested a review from ahl April 1, 2024 19:41
} else if let OperationParameterKind::Query(_) = param.kind {
// Query parameters are None; having page_token as Some(_)
// is mutually exclusive with other query parameters.
} else if param.api_name.as_str() != "limit"
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 the change I'm least sure about, but I think it's fine? We should only be here if we have a non-None dropshot_pagination, and dropshot_pagination_data explicitly checks for both "page_token" and "limit" as query parameters.

Copy link
Collaborator

@ahl ahl Apr 1, 2024

Choose a reason for hiding this comment

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

Yeah, this is the part I'm least sure about as well. My intention (unexpressed in any comments) is that the consumer might specify the size of the first page to optimize for latency and then rely on the server to give us chunky, throughput oriented pages subsequently. Imagine, for example, a CLI where we want to start printing output quickly.

Alternatively, would it make sense to have parameters for the first page and other pages?

In either case, if we don't include this change we might consider updating the function parameters docs which, currently, come from dropshot via the OpenAPI doc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alternatively, would it make sense to have parameters for the first page and other pages?

I thought about this. It doesn't seem unreasonable to me, although I suspect most clients ought to specify Some(small_value) for the first page and None (server choice) for the other pages, right? I wonder if it would help to put this in a new type specifically for these parameters for clarity? Totally spitballing, something like:

pub struct StreamPaginationLimits {
    // or just omit this one and recommend clients use `.take(_)`
    pub total: Option<NonZeroU32>,
    pub first_page: Option<NonZeroU32>,
    pub remaining_pages: Option<NonZeroU32>,
}

with helper methods for "let the server pick all the limits, I don't care" and "I just want a small first page, let the server pick for remaining pages".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another thought: I'm not sure the stream interface actually does the "small first page, larger subsequent pages" thing you want, although I guess it depends on the client. I think if you're using

while let Some(item) = stream.next() { .. }

with a first page limit of 10 and a subsequent page limit of 100, you'll incur the latency for the GET (10) on the first nex(), the next 9 will return immediately, then you'll incur the latency for GET (100) on the 11th call to next(), right?

@jgallagher jgallagher requested a review from bnaecker April 1, 2024 19:43
Copy link
Collaborator

@ahl ahl left a comment

Choose a reason for hiding this comment

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

Progenitor also emits the CLI. My intention with the --limit parameter for various list subcommands is that the limit impacts the total number of items output--not just the particular page size.

I expect we'd want to honor the limit by generating a take there (i.e. rather than in the obviously wrong position in the generated stream function).

Would it be superfluous to update the docs for these generated _stream() / .stream() functions to point consumers to .take() as a way to impose an outer limit or should that be implicit in the use of the stream (not sure why that didn't occur to me but FWIW it didn't).

} else if let OperationParameterKind::Query(_) = param.kind {
// Query parameters are None; having page_token as Some(_)
// is mutually exclusive with other query parameters.
} else if param.api_name.as_str() != "limit"
Copy link
Collaborator

@ahl ahl Apr 1, 2024

Choose a reason for hiding this comment

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

Yeah, this is the part I'm least sure about as well. My intention (unexpressed in any comments) is that the consumer might specify the size of the first page to optimize for latency and then rely on the server to give us chunky, throughput oriented pages subsequently. Imagine, for example, a CLI where we want to start printing output quickly.

Alternatively, would it make sense to have parameters for the first page and other pages?

In either case, if we don't include this change we might consider updating the function parameters docs which, currently, come from dropshot via the OpenAPI doc.

Copy link
Collaborator

@ahl ahl left a comment

Choose a reason for hiding this comment

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

there's similar code in method::builder_struct -- can you please update that similarly?

@jgallagher
Copy link
Contributor Author

there's similar code in method::builder_struct -- can you please update that similarly?

Done in faf3f72

@ahl
Copy link
Collaborator

ahl commented Apr 3, 2024

Looks good. Thanks

@ahl ahl merged commit 1a61bf1 into main Apr 3, 2024
6 checks passed
@ahl ahl deleted the fix-paginated-stream branch April 3, 2024 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Client paginated _stream() methods are confused about limit
3 participants