Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ It is meant to complement [go-github](https://github.com/google/go-github), but

If you like this package, please check out [go-github-pagination!](https://github.com/gofri/go-github-pagination)

### Migration from V1 to V2

TODO

## Recommended: Pagination Handling

If you like this package, please checkout [go-github-pagination](https://github.com/gofri/go-github-pagination).
Expand Down Expand Up @@ -51,7 +47,8 @@ func main() {

## Client Options

Both RoundTrippers support a set of options to configure their behavior and set callbacks. nil callbacks are treated as no-op.
Both RoundTrippers support a set of options to configure their behavior and set callbacks.
nil callbacks are treated as no-op.

### Primary Rate Limit Options:

Expand Down
2 changes: 1 addition & 1 deletion e2e_test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestGoGithubClientCompatability(t *testing.T) {

print := func(context *github_secondary_ratelimit.CallbackContext) {
t.Logf("Secondary rate limit reached! Sleeping for %.2f seconds [%v --> %v]",
time.Until(*context.SleepUntil).Seconds(), time.Now(), *context.SleepUntil)
time.Until(*context.ResetTime).Seconds(), time.Now(), *context.ResetTime)
}

orgLister := &orgLister{}
Expand Down
6 changes: 3 additions & 3 deletions github_ratelimit/github_secondary_ratelimit/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// Fields might be nillable, depending on the specific callback and field.
type CallbackContext struct {
RoundTripper *SecondaryRateLimiter
SleepUntil *time.Time // TODO rename to ResetTime to match primary
ResetTime *time.Time
TotalSleepTime *time.Duration
Request *http.Request
Response *http.Response
Expand All @@ -21,13 +21,13 @@ type CallbackContext struct {
type OnLimitDetected func(*CallbackContext)

// OnSingleLimitPassed is a callback to be called when a rate limit is exceeding the limit for a single sleep.
// The sleepUntil represents the end of sleep duration if the limit was not exceeded.
// The ResetTime represents the end of sleep duration if the limit was not exceeded.
// The totalSleepTime does not include the sleep (that is not going to happen).
// Note: called while holding the lock.
type OnSingleLimitExceeded func(*CallbackContext)

// OnTotalLimitExceeded is a callback to be called when a rate limit is exceeding the limit for the total sleep.
// The sleepUntil represents the end of sleep duration if the limit was not exceeded.
// The ResetTime represents the end of sleep duration if the limit was not exceeded.
// The totalSleepTime does not include the sleep (that is not going to happen).
// Note: called while holding the lock.
type OnTotalLimitExceeded func(*CallbackContext)
16 changes: 8 additions & 8 deletions github_ratelimit/github_secondary_ratelimit/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@ func parseSecondaryLimitTime(resp *http.Response) *time.Time {
return nil
}

if sleepUntil := parseRetryAfter(resp.Header); sleepUntil != nil {
return sleepUntil
if resetTime := parseRetryAfter(resp.Header); resetTime != nil {
return resetTime
}

if sleepUntil := parseXRateLimitReset(resp); sleepUntil != nil {
return sleepUntil
if resetTime := parseXRateLimitReset(resp); resetTime != nil {
return resetTime
}

// XXX: per GitHub API docs, we should default to a 60 seconds sleep duration in case the header is missing,
Expand All @@ -119,9 +119,9 @@ func parseRetryAfter(header http.Header) *time.Time {
}

// per GitHub API, the header is set to the number of seconds to wait
sleepUntil := time.Now().Add(time.Duration(retryAfterSeconds) * time.Second)
resetTime := time.Now().Add(time.Duration(retryAfterSeconds) * time.Second)

return &sleepUntil
return &resetTime
}

// parseXRateLimitReset parses the GitHub API response header in case a x-ratelimit-reset is returned.
Expand All @@ -134,9 +134,9 @@ func parseXRateLimitReset(resp *http.Response) *time.Time {
}

// per GitHub API, the header is set to the number of seconds since epoch (UTC)
sleepUntil := time.Unix(secondsSinceEpoch, 0)
resetTime := time.Unix(secondsSinceEpoch, 0)

return &sleepUntil
return &resetTime
}

// httpHeaderIntValue parses an integer value from the given HTTP header.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// SecondaryRateLimiter is a RoundTripper for handling GitHub secondary rate limits.
type SecondaryRateLimiter struct {
Base http.RoundTripper
sleepUntil *time.Time
resetTime *time.Time
lock sync.RWMutex
totalSleepTime time.Duration
config *Config
Expand Down Expand Up @@ -125,18 +125,18 @@ func (t *SecondaryRateLimiter) updateRateLimit(secondaryLimit time.Time, callbac
}

// a legitimate new limit
t.sleepUntil = &secondaryLimit
t.resetTime = &secondaryLimit
t.totalSleepTime += smoothSleepTime(sleepDuration)
t.triggerCallback(config.onLimitDetected, callbackContext, secondaryLimit)

return true
}

func (t *SecondaryRateLimiter) currentSleepDurationUnlocked() time.Duration {
if t.sleepUntil == nil {
if t.resetTime == nil {
return 0
}
return time.Until(*t.sleepUntil)
return time.Until(*t.resetTime)
}

func (t *SecondaryRateLimiter) triggerCallback(callback func(*CallbackContext), callbackContext *CallbackContext, newSleepUntil time.Time) {
Expand All @@ -145,7 +145,7 @@ func (t *SecondaryRateLimiter) triggerCallback(callback func(*CallbackContext),
}

callbackContext.RoundTripper = t
callbackContext.SleepUntil = &newSleepUntil
callbackContext.ResetTime = &newSleepUntil
callbackContext.TotalSleepTime = &t.totalSleepTime

callback(callbackContext)
Expand Down
4 changes: 2 additions & 2 deletions github_ratelimit/secondary_ratelimit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestSecondaryRateLimit(t *testing.T) {

print := func(context *github_secondary_ratelimit.CallbackContext) {
t.Logf("Secondary rate limit reached! Sleeping for %.2f seconds [%v --> %v]",
time.Until(*context.SleepUntil).Seconds(), time.Now(), *context.SleepUntil)
time.Until(*context.ResetTime).Seconds(), time.Now(), *context.ResetTime)
}

i := github_ratelimit_test.SetupSecondaryInjecter(t, every, sleep)
Expand Down Expand Up @@ -348,7 +348,7 @@ func TestCallbackContext(t *testing.T) {
if ctx.Request == nil || ctx.Response == nil {
t.Fatalf("missing request / response: %v / %v:", ctx.Request, ctx.Response)
}
if got, min, max := time.Until(*ctx.SleepUntil), time.Duration(0), sleep*time.Duration(requestNum.Load()); got <= min || got > max {
if got, min, max := time.Until(*ctx.ResetTime), time.Duration(0), sleep*time.Duration(requestNum.Load()); got <= min || got > max {
t.Fatalf("unexpected sleep until time: %v < %v <= %v", min, got, max)
}
if got, want := *ctx.TotalSleepTime, sleep*time.Duration(requestsCycle); got != want {
Expand Down
Loading