Skip to content

Commit 714ab71

Browse files
Ensure that all migration requests are cancellable (#12669)
* Ensure that all migration requests are cancellable Signed-off-by: Andrew Thornton <[email protected]> * Use WithContext as RequestWithContext is go 1.14 Signed-off-by: Andrew Thornton <[email protected]> Co-authored-by: techknowlogick <[email protected]>
1 parent 84eac6e commit 714ab71

File tree

7 files changed

+86
-39
lines changed

7 files changed

+86
-39
lines changed

modules/migrations/base/downloader.go

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Downloader interface {
3535

3636
// DownloaderFactory defines an interface to match a downloader implementation and create a downloader
3737
type DownloaderFactory interface {
38-
New(opts MigrateOptions) (Downloader, error)
38+
New(ctx context.Context, opts MigrateOptions) (Downloader, error)
3939
GitServiceType() structs.GitServiceType
4040
}
4141

@@ -46,21 +46,24 @@ var (
4646
// RetryDownloader retry the downloads
4747
type RetryDownloader struct {
4848
Downloader
49+
ctx context.Context
4950
RetryTimes int // the total execute times
5051
RetryDelay int // time to delay seconds
5152
}
5253

5354
// NewRetryDownloader creates a retry downloader
54-
func NewRetryDownloader(downloader Downloader, retryTimes, retryDelay int) *RetryDownloader {
55+
func NewRetryDownloader(ctx context.Context, downloader Downloader, retryTimes, retryDelay int) *RetryDownloader {
5556
return &RetryDownloader{
5657
Downloader: downloader,
58+
ctx: ctx,
5759
RetryTimes: retryTimes,
5860
RetryDelay: retryDelay,
5961
}
6062
}
6163

6264
// SetContext set context
6365
func (d *RetryDownloader) SetContext(ctx context.Context) {
66+
d.ctx = ctx
6467
d.Downloader.SetContext(ctx)
6568
}
6669

@@ -75,7 +78,11 @@ func (d *RetryDownloader) GetRepoInfo() (*Repository, error) {
7578
if repo, err = d.Downloader.GetRepoInfo(); err == nil {
7679
return repo, nil
7780
}
78-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
81+
select {
82+
case <-d.ctx.Done():
83+
return nil, d.ctx.Err()
84+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
85+
}
7986
}
8087
return nil, err
8188
}
@@ -91,7 +98,11 @@ func (d *RetryDownloader) GetTopics() ([]string, error) {
9198
if topics, err = d.Downloader.GetTopics(); err == nil {
9299
return topics, nil
93100
}
94-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
101+
select {
102+
case <-d.ctx.Done():
103+
return nil, d.ctx.Err()
104+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
105+
}
95106
}
96107
return nil, err
97108
}
@@ -107,7 +118,11 @@ func (d *RetryDownloader) GetMilestones() ([]*Milestone, error) {
107118
if milestones, err = d.Downloader.GetMilestones(); err == nil {
108119
return milestones, nil
109120
}
110-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
121+
select {
122+
case <-d.ctx.Done():
123+
return nil, d.ctx.Err()
124+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
125+
}
111126
}
112127
return nil, err
113128
}
@@ -123,7 +138,11 @@ func (d *RetryDownloader) GetReleases() ([]*Release, error) {
123138
if releases, err = d.Downloader.GetReleases(); err == nil {
124139
return releases, nil
125140
}
126-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
141+
select {
142+
case <-d.ctx.Done():
143+
return nil, d.ctx.Err()
144+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
145+
}
127146
}
128147
return nil, err
129148
}
@@ -139,7 +158,11 @@ func (d *RetryDownloader) GetLabels() ([]*Label, error) {
139158
if labels, err = d.Downloader.GetLabels(); err == nil {
140159
return labels, nil
141160
}
142-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
161+
select {
162+
case <-d.ctx.Done():
163+
return nil, d.ctx.Err()
164+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
165+
}
143166
}
144167
return nil, err
145168
}
@@ -156,7 +179,11 @@ func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) {
156179
if issues, isEnd, err = d.Downloader.GetIssues(page, perPage); err == nil {
157180
return issues, isEnd, nil
158181
}
159-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
182+
select {
183+
case <-d.ctx.Done():
184+
return nil, false, d.ctx.Err()
185+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
186+
}
160187
}
161188
return nil, false, err
162189
}
@@ -172,7 +199,11 @@ func (d *RetryDownloader) GetComments(issueNumber int64) ([]*Comment, error) {
172199
if comments, err = d.Downloader.GetComments(issueNumber); err == nil {
173200
return comments, nil
174201
}
175-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
202+
select {
203+
case <-d.ctx.Done():
204+
return nil, d.ctx.Err()
205+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
206+
}
176207
}
177208
return nil, err
178209
}
@@ -188,7 +219,11 @@ func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, er
188219
if prs, err = d.Downloader.GetPullRequests(page, perPage); err == nil {
189220
return prs, nil
190221
}
191-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
222+
select {
223+
case <-d.ctx.Done():
224+
return nil, d.ctx.Err()
225+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
226+
}
192227
}
193228
return nil, err
194229
}
@@ -204,7 +239,11 @@ func (d *RetryDownloader) GetReviews(pullRequestNumber int64) ([]*Review, error)
204239
if reviews, err = d.Downloader.GetReviews(pullRequestNumber); err == nil {
205240
return reviews, nil
206241
}
207-
time.Sleep(time.Second * time.Duration(d.RetryDelay))
242+
select {
243+
case <-d.ctx.Done():
244+
return nil, d.ctx.Err()
245+
case <-time.After(time.Second * time.Duration(d.RetryDelay)):
246+
}
208247
}
209248
return nil, err
210249
}

modules/migrations/gitea_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package migrations
77

88
import (
9+
"context"
910
"testing"
1011
"time"
1112

@@ -26,7 +27,7 @@ func TestGiteaUploadRepo(t *testing.T) {
2627
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 1}).(*models.User)
2728

2829
var (
29-
downloader = NewGithubDownloaderV3("", "", "", "go-xorm", "builder")
30+
downloader = NewGithubDownloaderV3(context.Background(), "", "", "", "go-xorm", "builder")
3031
repoName = "builder-" + time.Now().Format("2006-01-02-15-04-05")
3132
uploader = NewGiteaLocalUploader(graceful.GetManager().HammerContext(), user, user.Name, repoName)
3233
)

modules/migrations/github.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type GithubDownloaderV3Factory struct {
4141
}
4242

4343
// New returns a Downloader related to this factory according MigrateOptions
44-
func (f *GithubDownloaderV3Factory) New(opts base.MigrateOptions) (base.Downloader, error) {
44+
func (f *GithubDownloaderV3Factory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
4545
u, err := url.Parse(opts.CloneAddr)
4646
if err != nil {
4747
return nil, err
@@ -53,7 +53,7 @@ func (f *GithubDownloaderV3Factory) New(opts base.MigrateOptions) (base.Download
5353

5454
log.Trace("Create github downloader: %s/%s", oldOwner, oldName)
5555

56-
return NewGithubDownloaderV3(opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil
56+
return NewGithubDownloaderV3(ctx, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil
5757
}
5858

5959
// GitServiceType returns the type of git service
@@ -74,11 +74,11 @@ type GithubDownloaderV3 struct {
7474
}
7575

7676
// NewGithubDownloaderV3 creates a github Downloader via github v3 API
77-
func NewGithubDownloaderV3(userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 {
77+
func NewGithubDownloaderV3(ctx context.Context, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 {
7878
var downloader = GithubDownloaderV3{
7979
userName: userName,
8080
password: password,
81-
ctx: context.Background(),
81+
ctx: ctx,
8282
repoOwner: repoOwner,
8383
repoName: repoName,
8484
}

modules/migrations/github_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package migrations
77

88
import (
9+
"context"
910
"os"
1011
"testing"
1112
"time"
@@ -64,7 +65,7 @@ func assertLabelEqual(t *testing.T, name, color, description string, label *base
6465

6566
func TestGitHubDownloadRepo(t *testing.T) {
6667
GithubLimitRateRemaining = 3 //Wait at 3 remaining since we could have 3 CI in //
67-
downloader := NewGithubDownloaderV3("", "", os.Getenv("GITHUB_READ_TOKEN"), "go-gitea", "test_repo")
68+
downloader := NewGithubDownloaderV3(context.Background(), "", "", os.Getenv("GITHUB_READ_TOKEN"), "go-gitea", "test_repo")
6869
err := downloader.RefreshRate()
6970
assert.NoError(t, err)
7071

modules/migrations/gitlab.go

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type GitlabDownloaderFactory struct {
3535
}
3636

3737
// New returns a Downloader related to this factory according MigrateOptions
38-
func (f *GitlabDownloaderFactory) New(opts base.MigrateOptions) (base.Downloader, error) {
38+
func (f *GitlabDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) {
3939
u, err := url.Parse(opts.CloneAddr)
4040
if err != nil {
4141
return nil, err
@@ -47,7 +47,7 @@ func (f *GitlabDownloaderFactory) New(opts base.MigrateOptions) (base.Downloader
4747

4848
log.Trace("Create gitlab downloader. BaseURL: %s RepoName: %s", baseURL, repoNameSpace)
4949

50-
return NewGitlabDownloader(baseURL, repoNameSpace, opts.AuthUsername, opts.AuthPassword, opts.AuthToken), nil
50+
return NewGitlabDownloader(ctx, baseURL, repoNameSpace, opts.AuthUsername, opts.AuthPassword, opts.AuthToken), nil
5151
}
5252

5353
// GitServiceType returns the type of git service
@@ -73,7 +73,7 @@ type GitlabDownloader struct {
7373
// NewGitlabDownloader creates a gitlab Downloader via gitlab API
7474
// Use either a username/password, personal token entered into the username field, or anonymous/public access
7575
// Note: Public access only allows very basic access
76-
func NewGitlabDownloader(baseURL, repoPath, username, password, token string) *GitlabDownloader {
76+
func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, password, token string) *GitlabDownloader {
7777
var gitlabClient *gitlab.Client
7878
var err error
7979
if token != "" {
@@ -88,7 +88,7 @@ func NewGitlabDownloader(baseURL, repoPath, username, password, token string) *G
8888
}
8989

9090
// Grab and store project/repo ID here, due to issues using the URL escaped path
91-
gr, _, err := gitlabClient.Projects.GetProject(repoPath, nil, nil)
91+
gr, _, err := gitlabClient.Projects.GetProject(repoPath, nil, nil, gitlab.WithContext(ctx))
9292
if err != nil {
9393
log.Trace("Error retrieving project: %v", err)
9494
return nil
@@ -100,7 +100,7 @@ func NewGitlabDownloader(baseURL, repoPath, username, password, token string) *G
100100
}
101101

102102
return &GitlabDownloader{
103-
ctx: context.Background(),
103+
ctx: ctx,
104104
client: gitlabClient,
105105
repoID: gr.ID,
106106
repoName: gr.Name,
@@ -118,7 +118,7 @@ func (g *GitlabDownloader) GetRepoInfo() (*base.Repository, error) {
118118
return nil, errors.New("error: GitlabDownloader is nil")
119119
}
120120

121-
gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil)
121+
gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil, gitlab.WithContext(g.ctx))
122122
if err != nil {
123123
return nil, err
124124
}
@@ -158,7 +158,7 @@ func (g *GitlabDownloader) GetTopics() ([]string, error) {
158158
return nil, errors.New("error: GitlabDownloader is nil")
159159
}
160160

161-
gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil)
161+
gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil, gitlab.WithContext(g.ctx))
162162
if err != nil {
163163
return nil, err
164164
}
@@ -179,7 +179,7 @@ func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) {
179179
ListOptions: gitlab.ListOptions{
180180
Page: i,
181181
PerPage: perPage,
182-
}}, nil)
182+
}}, nil, gitlab.WithContext(g.ctx))
183183
if err != nil {
184184
return nil, err
185185
}
@@ -237,7 +237,7 @@ func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) {
237237
ls, _, err := g.client.Labels.ListLabels(g.repoID, &gitlab.ListLabelsOptions{
238238
Page: i,
239239
PerPage: perPage,
240-
}, nil)
240+
}, nil, gitlab.WithContext(g.ctx))
241241
if err != nil {
242242
return nil, err
243243
}
@@ -288,7 +288,7 @@ func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
288288
ls, _, err := g.client.Releases.ListReleases(g.repoID, &gitlab.ListReleasesOptions{
289289
Page: i,
290290
PerPage: perPage,
291-
}, nil)
291+
}, nil, gitlab.WithContext(g.ctx))
292292
if err != nil {
293293
return nil, err
294294
}
@@ -305,11 +305,18 @@ func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) {
305305

306306
// GetAsset returns an asset
307307
func (g *GitlabDownloader) GetAsset(tag string, id int64) (io.ReadCloser, error) {
308-
link, _, err := g.client.ReleaseLinks.GetReleaseLink(g.repoID, tag, int(id))
308+
link, _, err := g.client.ReleaseLinks.GetReleaseLink(g.repoID, tag, int(id), gitlab.WithContext(g.ctx))
309309
if err != nil {
310310
return nil, err
311311
}
312-
resp, err := http.Get(link.URL)
312+
313+
req, err := http.NewRequest("GET", link.URL, nil)
314+
if err != nil {
315+
return nil, err
316+
}
317+
req = req.WithContext(g.ctx)
318+
319+
resp, err := http.DefaultClient.Do(req)
313320
if err != nil {
314321
return nil, err
315322
}
@@ -336,7 +343,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
336343

337344
var allIssues = make([]*base.Issue, 0, perPage)
338345

339-
issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil)
346+
issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
340347
if err != nil {
341348
return nil, false, fmt.Errorf("error while listing issues: %v", err)
342349
}
@@ -393,14 +400,14 @@ func (g *GitlabDownloader) GetComments(issueNumber int64) ([]*base.Comment, erro
393400
comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(realIssueNumber), &gitlab.ListIssueDiscussionsOptions{
394401
Page: page,
395402
PerPage: 100,
396-
}, nil)
403+
}, nil, gitlab.WithContext(g.ctx))
397404
} else {
398405
// If this is a PR, we need to figure out the Gitlab/original PR ID to be passed below
399406
realIssueNumber = issueNumber - g.issueCount
400407
comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(realIssueNumber), &gitlab.ListMergeRequestDiscussionsOptions{
401408
Page: page,
402409
PerPage: 100,
403-
}, nil)
410+
}, nil, gitlab.WithContext(g.ctx))
404411
}
405412

406413
if err != nil {
@@ -455,7 +462,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
455462

456463
var allPRs = make([]*base.PullRequest, 0, perPage)
457464

458-
prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil)
465+
prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(g.ctx))
459466
if err != nil {
460467
return nil, fmt.Errorf("error while listing merge requests: %v", err)
461468
}
@@ -536,7 +543,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
536543
// GetReviews returns pull requests review
537544
func (g *GitlabDownloader) GetReviews(pullRequestNumber int64) ([]*base.Review, error) {
538545

539-
state, _, err := g.client.MergeRequestApprovals.GetApprovalState(g.repoID, int(pullRequestNumber))
546+
state, _, err := g.client.MergeRequestApprovals.GetApprovalState(g.repoID, int(pullRequestNumber), gitlab.WithContext(g.ctx))
540547
if err != nil {
541548
return nil, err
542549
}

modules/migrations/gitlab_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package migrations
66

77
import (
8+
"context"
89
"net/http"
910
"os"
1011
"testing"
@@ -27,7 +28,7 @@ func TestGitlabDownloadRepo(t *testing.T) {
2728
t.Skipf("Can't access test repo, skipping %s", t.Name())
2829
}
2930

30-
downloader := NewGitlabDownloader("https://gitlab.com", "gitea/test_repo", "", "", gitlabPersonalAccessToken)
31+
downloader := NewGitlabDownloader(context.Background(), "https://gitlab.com", "gitea/test_repo", "", "", gitlabPersonalAccessToken)
3132
if downloader == nil {
3233
t.Fatal("NewGitlabDownloader is nil")
3334
}

0 commit comments

Comments
 (0)