1
0
Fork 0

Add retry delay

pull/558/head
Dave Hadka 2020-08-17 15:32:04 -05:00
parent 1ef26b2390
commit de52c861c1
3 changed files with 30 additions and 11 deletions

View File

@ -20,7 +20,8 @@ async function handleResponse(
if (response.statusCode >= 900) {
throw Error('Test Error')
} else if (response.statusCode >= 600) {
const error: any = Error('Test Error with Status Code')
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const error = Error('Test Error with Status Code') as any
error['statusCode'] = response.statusCode - 300
throw error
} else {
@ -37,7 +38,9 @@ async function testRetryExpectingResult(
const actualResult = await retry(
'test',
async () => handleResponse(responses.pop()),
(response: TestResponse) => response.statusCode
(response: TestResponse) => response.statusCode,
2, // maxAttempts
0 // delay
)
expect(actualResult.result).toEqual(expectedResult)
@ -54,12 +57,14 @@ async function testRetryConvertingErrorToResult(
'test',
async () => handleResponse(responses.pop()),
(response: TestResponse) => response.statusCode,
2,
2, // maxAttempts
0, // delay
(e: Error) => {
const error: any = e
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const error = e as any
return {
statusCode: error['statusCode'],
result: error['result']
result: error['result'] ?? null
}
}
)
@ -77,7 +82,9 @@ async function testRetryExpectingError(
retry(
'test',
async () => handleResponse(responses.pop()),
(response: TestResponse) => response.statusCode
(response: TestResponse) => response.statusCode,
2, // maxAttempts,
0 // delay
)
).rejects.toBeInstanceOf(Error)
}

View File

@ -11,6 +11,9 @@ export enum CompressionMethod {
Zstd = 'zstd'
}
// The default delay in milliseconds between retry attempts.
export const RetryDelay = 5000
// Socket timeout in milliseconds during download. If no traffic is received
// over the socket during this period, the socket is destroyed and the download
// is aborted.

View File

@ -4,6 +4,7 @@ import {
IHttpClientResponse,
ITypedResponse
} from '@actions/http-client/interfaces'
import {RetryDelay} from './constants'
export function isSuccessStatusCode(statusCode?: number): boolean {
if (!statusCode) {
@ -31,11 +32,16 @@ export function isRetryableStatusCode(statusCode?: number): boolean {
return retryableStatusCodes.includes(statusCode)
}
async function sleep(milliseconds: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}
export async function retry<T>(
name: string,
method: () => Promise<T>,
getStatusCode: (arg0: T) => number | undefined,
maxAttempts = 2,
delay = RetryDelay,
onError: ((arg0: Error) => T | undefined) | undefined = undefined
): Promise<T> {
let errorMessage = ''
@ -79,6 +85,7 @@ export async function retry<T>(
break
}
await sleep(delay)
attempt++
}
@ -95,11 +102,12 @@ export async function retryTypedResponse<T>(
method,
(response: ITypedResponse<T>) => response.statusCode,
maxAttempts,
RetryDelay,
// If the error object contains the statusCode property, extract it and return
// an ITypedResponse<T> so it can be processed by the retry logic. Explicitly
// casting Error object to any to workaround missing property errors.
// an ITypedResponse<T> so it can be processed by the retry logic.
(e: Error) => {
const error : any = e
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const error = e as any
if (error['statusCode']) {
return {
statusCode: error['statusCode'],
@ -122,6 +130,7 @@ export async function retryHttpClientResponse<T>(
name,
method,
(response: IHttpClientResponse) => response.message.statusCode,
maxAttempts
maxAttempts,
RetryDelay
)
}