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

evaluations list pagination and filtering #11648

Merged
merged 6 commits into from
Dec 10, 2021
Merged

Conversation

tgross
Copy link
Member

@tgross tgross commented Dec 8, 2021

Fixes #11621

Add pagination to the Eval.List RPC by checking for pagination token
and page size in QueryOptions. This will allow resuming from the
last ID seen so long as the query parameters and the state store
itself are unchanged between requests.

Add filtering by job ID or evaluation status over the results we get
out of the state store.

Add a NextToken field to the structs.QueryMeta so that we have a
common field across RPCs to tell the caller where to resume paging
from on their next API call. Include this field on the api.QueryMeta
as well so that it's available for future versions of List HTTP APIs
that wrap the response with QueryMeta rather than returning a simple
list of structs.


Note to reviewers: this is probably best reviewed commit-by-commit. It's a large PR but most of the LoC is tests. @ChaiWithJai I've added you as a reviewer mostly so you can see the implications for how the UI will need to do paging.

@tgross tgross self-assigned this Dec 8, 2021
@tgross tgross force-pushed the f-evaluations-list-pagination branch from 87b5444 to f589249 Compare December 8, 2021 20:34
@tgross tgross marked this pull request as ready for review December 8, 2021 20:34
@tgross tgross requested review from lgfa29, DerekStrickland and ChaiWithJai and removed request for lgfa29 December 8, 2021 20:34
@tgross tgross added the theme/api HTTP API and SDK issues label Dec 8, 2021
@tgross tgross added this to the 1.2.3 milestone Dec 8, 2021
Copy link
Contributor

@lgfa29 lgfa29 left a comment

Choose a reason for hiding this comment

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

Nice!

Do you think we're at the point where it would be worth documenting the general flow of pagination in https://www.nomadproject.io/api-docs?

website/content/api-docs/evaluations.mdx Outdated Show resolved Hide resolved
api/api.go Outdated Show resolved Hide resolved
Copy link
Contributor

@DerekStrickland DerekStrickland left a comment

Choose a reason for hiding this comment

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

Found one copy-paste variable naming issue. Made some observations on the filtering method itself around readability and comments.

command/agent/http.go Outdated Show resolved Hide resolved
command/agent/http.go Show resolved Hide resolved
command/agent/http.go Outdated Show resolved Hide resolved
nomad/eval_endpoint.go Outdated Show resolved Hide resolved
nomad/eval_endpoint.go Outdated Show resolved Hide resolved
nomad/eval_endpoint.go Outdated Show resolved Hide resolved
nomad/eval_endpoint.go Outdated Show resolved Hide resolved
nomad/eval_endpoint.go Outdated Show resolved Hide resolved
nomad/eval_endpoint_test.go Outdated Show resolved Hide resolved
@lgfa29
Copy link
Contributor

lgfa29 commented Dec 9, 2021

After reading @DerekStrickland's comments I went over the code again to use the api package in a sample app and I noticed that its missing handling the new values in setQueryOptions.

This is the sample I used, but a test in api/evaluations_test.go would be helpful as well.

package main

import (
	"fmt"

	"github.com/hashicorp/nomad/api"
)

func main() {
	c, _ := api.NewClient(api.DefaultConfig())
	eval := c.Evaluations()
	lastToken := ""

	for {
		q := &api.QueryOptions{
			LastToken: lastToken,
			PerPage:   1,
		}

		l, qm, _ := eval.List(q)
		fmt.Printf("%v\n", l[0].ID)

		lastToken = qm.LastToken
		if qm.LastToken == "" {
			break
		}
	}
}

@tgross
Copy link
Member Author

tgross commented Dec 9, 2021

I noticed that its missing handling the new values in setQueryOptions.

Good catch. That also means we have a bug in the existing CSIVolumes.ListExternal API 🤦

@tgross
Copy link
Member Author

tgross commented Dec 9, 2021

Do you think we're at the point where it would be worth documenting the general flow of pagination in https://www.nomadproject.io/api-docs?

I definitely considered that but I figured I'd do that once we had a second example?

API queries can request pagination using the `NextToken` and `PerPage`
fields of `QueryOptions`, when supported by the underlying API.

Add a `NextToken` field to the `structs.QueryMeta` so that we have a
common field across RPCs to tell the caller where to resume paging
from on their next API call. Include this field on the `api.QueryMeta`
as well so that it's available for future versions of List HTTP APIs
that wrap the response with `QueryMeta` rather than returning a simple
list of structs. In the meantime callers can get the `X-Nomad-NextToken`.
Add pagination to the `Eval.List` RPC by checking for pagination token
and page size in `QueryOptions`. This will allow resuming from the
last ID seen so long as the query parameters and the state store
itself are unchanged between requests.

Add filtering by job ID or evaluation status over the results we get
out of the state store.
Parse the query parameters of the `Eval.List` API into the arguments
expected for filtering in the RPC call.
@tgross
Copy link
Member Author

tgross commented Dec 9, 2021

Ok @DerekStrickland @lgfa29 this should be ready for re-review. Thanks for sticking this one out... it's been a slog 😁

Refactor to expose only a Page method that populates the result set by
repeatedly calling an append function over the paged iterator.
Copy link
Contributor

@DerekStrickland DerekStrickland left a comment

Choose a reason for hiding this comment

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

:shipit:

@@ -69,8 +69,10 @@ type QueryOptions struct {
// paginated lists.
PerPage int32

// NextToken is the token used indicate where to start paging for queries
// that support paginated lists.
// NextToken is the token used to indicate where to start paging
Copy link
Contributor

Choose a reason for hiding this comment

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

It dawned on me last night, that we might need to keep PreviousToken too. This is not a blocker. Just a thought for conversation.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can't actually page backwards with the pager though -- you just call it with whatever the previous "next token" was (or with no token for the first page). So for now I'm going to call YAGNI on that and we can see if callers end up really needing it. 😀

@tgross tgross merged commit 972708a into main Dec 10, 2021
@tgross tgross deleted the f-evaluations-list-pagination branch December 10, 2021 18:43
@tgross tgross mentioned this pull request Dec 14, 2021
@github-actions
Copy link

github-actions bot commented Nov 7, 2022

I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
theme/api HTTP API and SDK issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

evaluations pagination & filtering
3 participants