diff options
author | Vasilii Iakliushin <viakliushin@gitlab.com> | 2021-10-13 14:21:18 +0300 |
---|---|---|
committer | Vasilii Iakliushin <viakliushin@gitlab.com> | 2021-10-20 15:41:42 +0300 |
commit | 27b02714920d8ba8b451eb26d19395e7f692589b (patch) | |
tree | 05a550bfd4618c59a02e6553178d693be00843b4 /internal/gitaly/service/ref/refs.go | |
parent | aec413230e6bce8782ae72d95d2d3cb312ebe923 (diff) |
Add pagination support for FindAllTags RPC
Contributes to https://gitlab.com/gitlab-org/gitlab/-/issues/340591
**Problem**
FindAllTags request does not support pagination parameters. Lack of
pagination causes performance issues for repositories with many tags.
**Solution**
Add pagination parameter support similar to what we use for
FindLocalBranches.
Changelog: added
Diffstat (limited to 'internal/gitaly/service/ref/refs.go')
-rw-r--r-- | internal/gitaly/service/ref/refs.go | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/internal/gitaly/service/ref/refs.go b/internal/gitaly/service/ref/refs.go index d6e2f2930..658d019b8 100644 --- a/internal/gitaly/service/ref/refs.go +++ b/internal/gitaly/service/ref/refs.go @@ -22,6 +22,20 @@ const ( tagFormat = "%(objectname) %(objecttype) %(refname:lstrip=2)" ) +type paginationOpts struct { + // Limit allows to set the maximum numbers of elements + Limit int + // IsPageToken allows control over which results are sent as part of the + // response. When IsPageToken evaluates to true for the first time, + // results will start to be sent as part of the response. This function + // will be called with an empty slice previous to sending the first line + // in order to allow sending everything right from the beginning. + IsPageToken func([]byte) bool + // When PageTokenError is true then the response will return an error when + // PageToken is not found. + PageTokenError bool +} + type findRefsOpts struct { cmdArgs []git.Option delim byte @@ -144,7 +158,7 @@ func (s *server) findLocalBranches(in *gitalypb.FindLocalBranchesRequest, stream } writer := newFindLocalBranchesWriter(stream, objectReader) - opts := paginationParamsToOpts(ctx, in.GetPaginationParams()) + opts := buildFindRefsOpts(ctx, in.GetPaginationParams()) opts.cmdArgs = []git.Option{ // %00 inserts the null character into the output (see for-each-ref docs) git.Flag{Name: "--format=" + strings.Join(localBranchFormatFields, "%00")}, @@ -195,7 +209,7 @@ func (s *server) findAllBranches(in *gitalypb.FindAllBranchesRequest, stream git return err } - opts := paginationParamsToOpts(ctx, nil) + opts := buildFindRefsOpts(ctx, nil) opts.cmdArgs = args writer := newFindAllBranchesWriter(stream, objectReader) @@ -306,8 +320,8 @@ func (s *server) validateFindTagRequest(in *gitalypb.FindTagRequest) error { return nil } -func paginationParamsToOpts(ctx context.Context, p *gitalypb.PaginationParameter) *findRefsOpts { - opts := &findRefsOpts{delim: '\n'} +func buildPaginationOpts(ctx context.Context, p *gitalypb.PaginationParameter) *paginationOpts { + opts := &paginationOpts{} opts.IsPageToken = func(_ []byte) bool { return true } opts.Limit = math.MaxInt32 @@ -338,6 +352,17 @@ func paginationParamsToOpts(ctx context.Context, p *gitalypb.PaginationParameter return opts } +func buildFindRefsOpts(ctx context.Context, p *gitalypb.PaginationParameter) *findRefsOpts { + opts := buildPaginationOpts(ctx, p) + + refsOpts := &findRefsOpts{delim: '\n'} + refsOpts.Limit = opts.Limit + refsOpts.IsPageToken = opts.IsPageToken + refsOpts.PageTokenError = opts.PageTokenError + + return refsOpts +} + // getTagSortField returns a field that needs to be used to sort the tags. // If sorting is not provided the default sorting is used: by refname. func getTagSortField(sortBy *gitalypb.FindAllTagsRequest_SortBy) (string, error) { |