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  }