Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Add configurable option to wait for GitHub external rate limiter#48423

Merged
pjlast merged 18 commits into
mainfrom
pjlast/github-client-wait-for-rate-limit
Mar 3, 2023
Merged

Add configurable option to wait for GitHub external rate limiter#48423
pjlast merged 18 commits into
mainfrom
pjlast/github-client-wait-for-rate-limit

Conversation

@pjlast

@pjlast pjlast commented Mar 1, 2023

Copy link
Copy Markdown
Contributor

Closes #48540

Sets the default GitHub rate limit to infinite, and adds an option to the V3Client to wait based on the rate limit headers returned by GitHub.

Before this PR
The default rate limit is set to 5000/3600 when no rate limit default is set, which severely handicaps our interactions with GitHub. It is also a poor approximation for the actual rate limit from GitHub's side.

After this PR
Now, if specified, the client will check the provided headers from GItHub and if a rate limit is hit, it will wait the specified amount of time before retrying. This may be quite a long time depending on which rate limit is hit, but it also does not make sense to fail the job when the rate limit is hit and have impartial data.

Test plan

Tests adjusted.

@pjlast pjlast requested review from a team and mrnugget March 1, 2023 13:11
@pjlast pjlast marked this pull request as ready for review March 1, 2023 13:11
@sourcegraph-bot

sourcegraph-bot commented Mar 1, 2023

Copy link
Copy Markdown
Contributor

Codenotify: Notifying subscribers in CODENOTIFY files for diff 967b4a1...ea7c94b.

Notify File(s)
@eseliger internal/extsvc/github/v3.go
internal/extsvc/github/v3_test.go
internal/extsvc/types.go
internal/extsvc/types_test.go
@indradhanush internal/repos/github.go
internal/repos/types_test.go
@sashaostrikov internal/repos/github.go
internal/repos/types_test.go
@sourcegraph/delivery doc/admin/external_service/github.md
@unknwon enterprise/internal/authz/github/client.go
enterprise/internal/authz/github/github.go
enterprise/internal/authz/github/mocks_test.go

Comment thread internal/extsvc/types.go
Comment thread enterprise/internal/authz/github/client.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
@pjlast pjlast requested a review from a team March 3, 2023 09:17

@mrnugget mrnugget left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Drive-by comments before hopping into meeting

Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
// We assert that two requests happened
assert.True(t, succeeded)
assert.False(t, hitSecondaryLimit)
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd add a happy case here too

Comment thread doc/admin/external_service/github.md
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/extsvc/github/v3.go Outdated
Comment thread internal/repos/github.go
}
var pageOrgs []*github.Org
pageOrgs, hasNextPage, cost, err = s.v3Client.GetAuthenticatedUserOrgsForPage(ctx, page)
pageOrgs, hasNextPage, _, err = s.v3Client.GetAuthenticatedUserOrgsForPage(ctx, page)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In next iteration, should we remove the cost from returned parameters of that function? Do we still need it in other places?

@mrnugget mrnugget left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cool! Good move on adding that method. I suggest also testing this locally with lots of print-statements to make sure everything really works like it should

Comment thread internal/extsvc/github/v3_test.go Outdated

@kopancek kopancek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks much cleaner to me, thanks!

@pjlast pjlast merged commit 7696b8c into main Mar 3, 2023
@pjlast pjlast deleted the pjlast/github-client-wait-for-rate-limit branch March 3, 2023 12:15
@mrnugget

mrnugget commented Mar 3, 2023

Copy link
Copy Markdown
Contributor

btw. what about the GitHub v4 client?

@eseliger eseliger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice work :)

Comment on lines +172 to +175
if remaining := c.retry.Sub(c.now()); remaining > 0 {
timeutil.SleepWithContext(ctx, remaining)
return true
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what the go rate limiter does, and I think we would want here, too is that it also checks the context deadline. If the time by which we could run the request is post-deadline, we can fail immediately instead of sleeping for long.

Comment thread internal/repos/github.go
for resource, monitor := range map[string]*ratelimit.Monitor{
"rest": v3Client.RateLimitMonitor(),
"rest": v3Client.ExternalRateLimiter(),
"graphql": v4Client.RateLimitMonitor(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

any chance we could get this for v4, too or is this not required? Asking for a batch changes friend.


GetAuthenticatedOAuthScopes(ctx context.Context) ([]string, error)
WithAuthenticator(auther auth.Authenticator) client
SetWaitForRateLimit(wait bool)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this seems unused from the diff 🤔

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GitHub

5 participants