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

Setting MaxItems to a low value when calling ZonesListAll may drastically reduce performance. #47

Open
com-m opened this issue Jul 31, 2019 · 3 comments
Labels
hacktoberfest kind/bug Something isn't working

Comments

@com-m
Copy link
Contributor

com-m commented Jul 31, 2019

Expected Behavior:
Function quickly returns with an array no greater in length than the maxItems parameter

Actual Behavior:
If the server response contains a "nextID" field, and the number of potential responses is high for the given query, the function will continually make requests to the server maxItems at a time until all potential responses have been exhausted. This can result in ZoneListAll taking an extended period of time to return, and eventually returning an array longer than the maxItems parameter.

How to reproduce:
Run unit tests for the zone functions in the client, mocking a backend that sends the appropriate test fixtures for the request.
If maxItems is set to 1, two requests will be sent and two items will be returned in the array instead of one.

@britneywright britneywright added kind/bug Something isn't working hacktoberfest labels Oct 25, 2019
@jranson
Copy link

jranson commented Sep 21, 2020

@com-m I started looking at this issue in case i can fix it up for Hacktoberfest2020, but i think there is a misunderstanding about the functionality, and want to make sure this isn't actually working as designed already.

In looking @ the VinylDNS API specification I see this:

maxItems: The number of items to return in the page. Valid values are 1 - 100. Defaults to 100 if not provided.

In the golang client code, i see that the description of the ZonesListAll function is commented as follows:

// ZonesListAll retrieves the complete list of zones with the ListFilter criteria passed.
// Handles paging through results on the user's behalf.

So the maxItems flag appears to only matter for paginating the API to collect the records, while the golang client will always pull all zones. If you use maxItems = 1 in the golang client, you should still expect to get all zones, it will just request one item at a time from the server. It probably makes sense to always use maxItems = 100 with no expectation of limiting the result set.

@remerle
Copy link
Member

remerle commented Sep 22, 2020

This seems like it's working as it was designed, but that design leaves something to be desired. I would expect MaxItems to limit the number of items returned, not control the internal (hidden) pagination. It seems to be a pattern repeated with the *All methods:

// ZoneChangesListAll retrieves the complete list of zone changes with the ListFilter criteria passed.
// Handles paging through results on the user's behalf.
func (c *Client) ZoneChangesListAll(zoneID string, filter ListFilter) ([]ZoneChange, error) {
if filter.MaxItems > 100 {
return nil, fmt.Errorf("MaxItems must be between 1 and 100")
}

We either need to not allow the user to affect the page size, or actually limit the number of results returned.

Perhaps we can add a RetrieveAllPages bool flag to the ListFilter? This would cause MaxItems to be ignored and it will be defaulted to 100.

// ListFilter represents the list query parameters that may be passed to
// VinylDNS API endpoints such as /zones and /zones/${zone_id}/recordsets
type ListFilter struct {
NameFilter string
StartFrom string
MaxItems int
}

@mdb What do you think about this. I don't want to break backward compatibility, so we'd need to default RetreiveAllPages to true. I haven't looked at all the code to see if this makes sense. However, the current implementation is a bit counter-intuitive.

@mdb
Copy link
Collaborator

mdb commented Oct 16, 2020

@remerle Apologies for the delayed response, here.

This seems like it's working as it was designed, but that design leaves something to be desired.

Yes; I agree with this assessment. the *All-named methods are typically intended to handle paging on users' behalf.

Perhaps we can add a RetrieveAllPages bool flag to the ListFilter? This would cause MaxItems to be ignored and it will be defaulted to 100.

I think this sounds reasonable, assuming there isn't ever a scenario where a ListFilter is passed to a method that will ignore RetrieveAllPages: true (I don't believe there is, currently), in which case the option would be similarly misleading to users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hacktoberfest kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants