You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

retry_downloader.go 3.8KB

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