code.gitea.io/gitea@v1.19.3/modules/migration/retry_downloader.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package migration 5 6 import ( 7 "context" 8 "time" 9 ) 10 11 var _ Downloader = &RetryDownloader{} 12 13 // RetryDownloader retry the downloads 14 type RetryDownloader struct { 15 Downloader 16 ctx context.Context 17 RetryTimes int // the total execute times 18 RetryDelay int // time to delay seconds 19 } 20 21 // NewRetryDownloader creates a retry downloader 22 func NewRetryDownloader(ctx context.Context, downloader Downloader, retryTimes, retryDelay int) *RetryDownloader { 23 return &RetryDownloader{ 24 Downloader: downloader, 25 ctx: ctx, 26 RetryTimes: retryTimes, 27 RetryDelay: retryDelay, 28 } 29 } 30 31 func (d *RetryDownloader) retry(work func() error) error { 32 var ( 33 times = d.RetryTimes 34 err error 35 ) 36 for ; times > 0; times-- { 37 if err = work(); err == nil { 38 return nil 39 } 40 if IsErrNotSupported(err) { 41 return err 42 } 43 select { 44 case <-d.ctx.Done(): 45 return d.ctx.Err() 46 case <-time.After(time.Second * time.Duration(d.RetryDelay)): 47 } 48 } 49 return err 50 } 51 52 // SetContext set context 53 func (d *RetryDownloader) SetContext(ctx context.Context) { 54 d.ctx = ctx 55 d.Downloader.SetContext(ctx) 56 } 57 58 // GetRepoInfo returns a repository information with retry 59 func (d *RetryDownloader) GetRepoInfo() (*Repository, error) { 60 var ( 61 repo *Repository 62 err error 63 ) 64 65 err = d.retry(func() error { 66 repo, err = d.Downloader.GetRepoInfo() 67 return err 68 }) 69 70 return repo, err 71 } 72 73 // GetTopics returns a repository's topics with retry 74 func (d *RetryDownloader) GetTopics() ([]string, error) { 75 var ( 76 topics []string 77 err error 78 ) 79 80 err = d.retry(func() error { 81 topics, err = d.Downloader.GetTopics() 82 return err 83 }) 84 85 return topics, err 86 } 87 88 // GetMilestones returns a repository's milestones with retry 89 func (d *RetryDownloader) GetMilestones() ([]*Milestone, error) { 90 var ( 91 milestones []*Milestone 92 err error 93 ) 94 95 err = d.retry(func() error { 96 milestones, err = d.Downloader.GetMilestones() 97 return err 98 }) 99 100 return milestones, err 101 } 102 103 // GetReleases returns a repository's releases with retry 104 func (d *RetryDownloader) GetReleases() ([]*Release, error) { 105 var ( 106 releases []*Release 107 err error 108 ) 109 110 err = d.retry(func() error { 111 releases, err = d.Downloader.GetReleases() 112 return err 113 }) 114 115 return releases, err 116 } 117 118 // GetLabels returns a repository's labels with retry 119 func (d *RetryDownloader) GetLabels() ([]*Label, error) { 120 var ( 121 labels []*Label 122 err error 123 ) 124 125 err = d.retry(func() error { 126 labels, err = d.Downloader.GetLabels() 127 return err 128 }) 129 130 return labels, err 131 } 132 133 // GetIssues returns a repository's issues with retry 134 func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) { 135 var ( 136 issues []*Issue 137 isEnd bool 138 err error 139 ) 140 141 err = d.retry(func() error { 142 issues, isEnd, err = d.Downloader.GetIssues(page, perPage) 143 return err 144 }) 145 146 return issues, isEnd, err 147 } 148 149 // GetComments returns a repository's comments with retry 150 func (d *RetryDownloader) GetComments(commentable Commentable) ([]*Comment, bool, error) { 151 var ( 152 comments []*Comment 153 isEnd bool 154 err error 155 ) 156 157 err = d.retry(func() error { 158 comments, isEnd, err = d.Downloader.GetComments(commentable) 159 return err 160 }) 161 162 return comments, isEnd, err 163 } 164 165 // GetPullRequests returns a repository's pull requests with retry 166 func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) { 167 var ( 168 prs []*PullRequest 169 err error 170 isEnd bool 171 ) 172 173 err = d.retry(func() error { 174 prs, isEnd, err = d.Downloader.GetPullRequests(page, perPage) 175 return err 176 }) 177 178 return prs, isEnd, err 179 } 180 181 // GetReviews returns pull requests reviews 182 func (d *RetryDownloader) GetReviews(reviewable Reviewable) ([]*Review, error) { 183 var ( 184 reviews []*Review 185 err error 186 ) 187 188 err = d.retry(func() error { 189 reviews, err = d.Downloader.GetReviews(reviewable) 190 return err 191 }) 192 193 return reviews, err 194 }