2019-05-07 04:12:51 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Copyright 2018 Jonas Franz. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package base
2019-11-16 11:30:06 +03:00
import (
2019-12-17 07:16:54 +03:00
"context"
2020-08-28 04:36:37 +03:00
"io"
2019-11-16 11:30:06 +03:00
"time"
"code.gitea.io/gitea/modules/structs"
)
2019-10-14 09:10:42 +03:00
2020-08-28 04:36:37 +03:00
// AssetDownloader downloads an asset (attachment) for a release
type AssetDownloader interface {
GetAsset ( tag string , id int64 ) ( io . ReadCloser , error )
}
2019-05-07 04:12:51 +03:00
// Downloader downloads the site repo informations
type Downloader interface {
2020-08-28 04:36:37 +03:00
AssetDownloader
2019-12-17 07:16:54 +03:00
SetContext ( context . Context )
2019-05-07 04:12:51 +03:00
GetRepoInfo ( ) ( * Repository , error )
2019-08-14 09:16:12 +03:00
GetTopics ( ) ( [ ] string , error )
2019-05-07 04:12:51 +03:00
GetMilestones ( ) ( [ ] * Milestone , error )
GetReleases ( ) ( [ ] * Release , error )
GetLabels ( ) ( [ ] * Label , error )
2019-05-30 23:26:57 +03:00
GetIssues ( page , perPage int ) ( [ ] * Issue , bool , error )
2019-05-07 04:12:51 +03:00
GetComments ( issueNumber int64 ) ( [ ] * Comment , error )
2019-05-30 23:26:57 +03:00
GetPullRequests ( page , perPage int ) ( [ ] * PullRequest , error )
2020-01-23 20:28:15 +03:00
GetReviews ( pullRequestNumber int64 ) ( [ ] * Review , error )
2019-05-07 04:12:51 +03:00
}
// DownloaderFactory defines an interface to match a downloader implementation and create a downloader
type DownloaderFactory interface {
2020-09-02 20:49:25 +03:00
New ( ctx context . Context , opts MigrateOptions ) ( Downloader , error )
2019-10-14 09:10:42 +03:00
GitServiceType ( ) structs . GitServiceType
2019-05-07 04:12:51 +03:00
}
2019-11-16 11:30:06 +03:00
2019-12-17 07:16:54 +03:00
var (
_ Downloader = & RetryDownloader { }
)
2019-11-16 11:30:06 +03:00
// RetryDownloader retry the downloads
type RetryDownloader struct {
Downloader
2020-09-02 20:49:25 +03:00
ctx context . Context
2019-11-16 11:30:06 +03:00
RetryTimes int // the total execute times
RetryDelay int // time to delay seconds
}
// NewRetryDownloader creates a retry downloader
2020-09-02 20:49:25 +03:00
func NewRetryDownloader ( ctx context . Context , downloader Downloader , retryTimes , retryDelay int ) * RetryDownloader {
2019-11-16 11:30:06 +03:00
return & RetryDownloader {
Downloader : downloader ,
2020-09-02 20:49:25 +03:00
ctx : ctx ,
2019-11-16 11:30:06 +03:00
RetryTimes : retryTimes ,
RetryDelay : retryDelay ,
}
}
2019-12-17 07:16:54 +03:00
// SetContext set context
func ( d * RetryDownloader ) SetContext ( ctx context . Context ) {
2020-09-02 20:49:25 +03:00
d . ctx = ctx
2019-12-17 07:16:54 +03:00
d . Downloader . SetContext ( ctx )
}
2019-11-16 11:30:06 +03:00
// GetRepoInfo returns a repository information with retry
func ( d * RetryDownloader ) GetRepoInfo ( ) ( * Repository , error ) {
var (
times = d . RetryTimes
repo * Repository
err error
)
for ; times > 0 ; times -- {
if repo , err = d . Downloader . GetRepoInfo ( ) ; err == nil {
return repo , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
// GetTopics returns a repository's topics with retry
func ( d * RetryDownloader ) GetTopics ( ) ( [ ] string , error ) {
var (
times = d . RetryTimes
topics [ ] string
err error
)
for ; times > 0 ; times -- {
if topics , err = d . Downloader . GetTopics ( ) ; err == nil {
return topics , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
// GetMilestones returns a repository's milestones with retry
func ( d * RetryDownloader ) GetMilestones ( ) ( [ ] * Milestone , error ) {
var (
times = d . RetryTimes
milestones [ ] * Milestone
err error
)
for ; times > 0 ; times -- {
if milestones , err = d . Downloader . GetMilestones ( ) ; err == nil {
return milestones , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
// GetReleases returns a repository's releases with retry
func ( d * RetryDownloader ) GetReleases ( ) ( [ ] * Release , error ) {
var (
times = d . RetryTimes
releases [ ] * Release
err error
)
for ; times > 0 ; times -- {
if releases , err = d . Downloader . GetReleases ( ) ; err == nil {
return releases , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
// GetLabels returns a repository's labels with retry
func ( d * RetryDownloader ) GetLabels ( ) ( [ ] * Label , error ) {
var (
times = d . RetryTimes
labels [ ] * Label
err error
)
for ; times > 0 ; times -- {
if labels , err = d . Downloader . GetLabels ( ) ; err == nil {
return labels , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
// GetIssues returns a repository's issues with retry
func ( d * RetryDownloader ) GetIssues ( page , perPage int ) ( [ ] * Issue , bool , error ) {
var (
times = d . RetryTimes
issues [ ] * Issue
isEnd bool
err error
)
for ; times > 0 ; times -- {
if issues , isEnd , err = d . Downloader . GetIssues ( page , perPage ) ; err == nil {
return issues , isEnd , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , false , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , false , err
}
// GetComments returns a repository's comments with retry
func ( d * RetryDownloader ) GetComments ( issueNumber int64 ) ( [ ] * Comment , error ) {
var (
times = d . RetryTimes
comments [ ] * Comment
err error
)
for ; times > 0 ; times -- {
if comments , err = d . Downloader . GetComments ( issueNumber ) ; err == nil {
return comments , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
// GetPullRequests returns a repository's pull requests with retry
func ( d * RetryDownloader ) GetPullRequests ( page , perPage int ) ( [ ] * PullRequest , error ) {
var (
times = d . RetryTimes
prs [ ] * PullRequest
err error
)
for ; times > 0 ; times -- {
if prs , err = d . Downloader . GetPullRequests ( page , perPage ) ; err == nil {
return prs , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2019-11-16 11:30:06 +03:00
}
return nil , err
}
2020-04-20 05:23:28 +03:00
// GetReviews returns pull requests reviews
func ( d * RetryDownloader ) GetReviews ( pullRequestNumber int64 ) ( [ ] * Review , error ) {
var (
times = d . RetryTimes
reviews [ ] * Review
err error
)
for ; times > 0 ; times -- {
if reviews , err = d . Downloader . GetReviews ( pullRequestNumber ) ; err == nil {
return reviews , nil
}
2020-09-02 20:49:25 +03:00
select {
case <- d . ctx . Done ( ) :
return nil , d . ctx . Err ( )
case <- time . After ( time . Second * time . Duration ( d . RetryDelay ) ) :
}
2020-04-20 05:23:28 +03:00
}
return nil , err
}