mirror of
https://github.com/actions/checkout.git
synced 2026-06-21 14:09:53 +08:00
Switch the shared retry helper from randomized delays to exponential backoff so transient GitHub 500 errors are retried predictably. Add coverage for the backoff sequence and regenerate the bundled dist output. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
import * as core from '@actions/core'
|
|
|
|
const defaultMaxAttempts = 3
|
|
const defaultMinSeconds = 10
|
|
const defaultMaxSeconds = 20
|
|
|
|
export class RetryHelper {
|
|
private maxAttempts: number
|
|
private minSeconds: number
|
|
private maxSeconds: number
|
|
|
|
constructor(
|
|
maxAttempts: number = defaultMaxAttempts,
|
|
minSeconds: number = defaultMinSeconds,
|
|
maxSeconds: number = defaultMaxSeconds
|
|
) {
|
|
this.maxAttempts = maxAttempts
|
|
this.minSeconds = Math.floor(minSeconds)
|
|
this.maxSeconds = Math.floor(maxSeconds)
|
|
if (this.minSeconds > this.maxSeconds) {
|
|
throw new Error('min seconds should be less than or equal to max seconds')
|
|
}
|
|
}
|
|
|
|
async execute<T>(action: () => Promise<T>): Promise<T> {
|
|
let attempt = 1
|
|
while (attempt < this.maxAttempts) {
|
|
// Try
|
|
try {
|
|
return await action()
|
|
} catch (err) {
|
|
core.info((err as any)?.message)
|
|
}
|
|
|
|
// Sleep
|
|
const seconds = this.getSleepAmount(attempt)
|
|
core.info(`Waiting ${seconds} seconds before trying again`)
|
|
await this.sleep(seconds)
|
|
attempt++
|
|
}
|
|
|
|
// Last attempt
|
|
return await action()
|
|
}
|
|
|
|
private getSleepAmount(attempt: number): number {
|
|
if (this.minSeconds === 0) {
|
|
return 0
|
|
}
|
|
|
|
return Math.min(this.minSeconds * Math.pow(2, attempt - 1), this.maxSeconds)
|
|
}
|
|
|
|
private async sleep(seconds: number): Promise<void> {
|
|
return new Promise(resolve => setTimeout(resolve, seconds * 1000))
|
|
}
|
|
}
|
|
|
|
export async function execute<T>(action: () => Promise<T>): Promise<T> {
|
|
const retryHelper = new RetryHelper()
|
|
return await retryHelper.execute(action)
|
|
}
|