retry-helper.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import * as core from '@actions/core'
  2. const defaultMaxAttempts = 3
  3. const defaultMinSeconds = 10
  4. const defaultMaxSeconds = 20
  5. export class RetryHelper {
  6. private maxAttempts: number
  7. private minSeconds: number
  8. private maxSeconds: number
  9. constructor(
  10. maxAttempts: number = defaultMaxAttempts,
  11. minSeconds: number = defaultMinSeconds,
  12. maxSeconds: number = defaultMaxSeconds
  13. ) {
  14. this.maxAttempts = maxAttempts
  15. this.minSeconds = Math.floor(minSeconds)
  16. this.maxSeconds = Math.floor(maxSeconds)
  17. }
  18. async execute<T>(action: () => Promise<T>): Promise<T> {
  19. let attempt = 1
  20. while (attempt < this.maxAttempts) {
  21. // Try
  22. try {
  23. return await action()
  24. } catch (err) {
  25. core.info(err.message)
  26. }
  27. // Sleep
  28. const seconds = this.getSleepAmount()
  29. core.info(`Waiting ${seconds} seconds before trying again`)
  30. await this.sleep(seconds)
  31. attempt++
  32. }
  33. // Last attempt
  34. return await action()
  35. }
  36. private getSleepAmount(): number {
  37. return (
  38. Math.floor(Math.random() * (this.maxSeconds - this.minSeconds + 1)) +
  39. this.minSeconds
  40. )
  41. }
  42. private async sleep(seconds: number): Promise<void> {
  43. return new Promise(resolve => setTimeout(resolve, seconds * 1000))
  44. }
  45. }
  46. export async function execute<T>(action: () => Promise<T>): Promise<T> {
  47. const retryHelper = new RetryHelper()
  48. return await retryHelper.execute(action)
  49. }