diff --git a/services/migrations/github.go b/services/migrations/github.go index 0dba3111674..952bca78819 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -152,12 +152,16 @@ func (g *GithubDownloaderV3) waitAndPickClient(ctx context.Context) { var recentIdx int var maxRemaining int for i := 0; i < len(g.clients); i++ { - if g.rates[i] != nil && g.rates[i].Remaining > maxRemaining { + if g.rates[i] == nil { // probe unknown clients once, else their rate never gets learned + g.curClientIdx = i + return + } + if g.rates[i].Remaining > maxRemaining { maxRemaining = g.rates[i].Remaining recentIdx = i } } - g.curClientIdx = recentIdx // if no max remain, it will always pick the first client. + g.curClientIdx = recentIdx for g.rates[g.curClientIdx] != nil && g.rates[g.curClientIdx].Remaining <= GithubLimitRateRemaining { timer := time.NewTimer(time.Until(g.rates[g.curClientIdx].Reset.Time)) diff --git a/services/migrations/github_test.go b/services/migrations/github_test.go index 53ac4b8f99b..dab7812a367 100644 --- a/services/migrations/github_test.go +++ b/services/migrations/github_test.go @@ -14,6 +14,7 @@ import ( "gitea.dev/models/unittest" base "gitea.dev/modules/migration" + "github.com/google/go-github/v88/github" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -473,3 +474,25 @@ func TestGithubMultiToken(t *testing.T) { }) } } + +func TestGithubMultiTokenClientSelection(t *testing.T) { + downloader := &GithubDownloaderV3{ + clients: make([]*github.Client, 3), + rates: make([]*github.Rate, 3), + } + + downloader.waitAndPickClient(t.Context()) + assert.Equal(t, 0, downloader.curClientIdx) + + downloader.rates[0] = &github.Rate{Remaining: 100} + downloader.waitAndPickClient(t.Context()) + assert.Equal(t, 1, downloader.curClientIdx) + + downloader.rates[1] = &github.Rate{Remaining: 200} + downloader.waitAndPickClient(t.Context()) + assert.Equal(t, 2, downloader.curClientIdx) + + downloader.rates[2] = &github.Rate{Remaining: 50} + downloader.waitAndPickClient(t.Context()) + assert.Equal(t, 1, downloader.curClientIdx) +}