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.9KB

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