Skip to content

Commit 3adfb57

Browse files
committed
feat(backoff): added ability to configure number of retries and starting backoff
1 parent b37ad3e commit 3adfb57

File tree

1 file changed

+46
-41
lines changed

1 file changed

+46
-41
lines changed

source/packages/@aws-accelerator/utils/lib/throttle.ts

+46-41
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
import { backOff, IBackOffOptions } from 'exponential-backoff';
1515

16+
const startingDelay = Number(process.env['STARTING_DELAY'] ?? 150);
17+
const numberOfRetries = Number(process.env['NUMBER_OF_RETRIES'] ?? 12);
18+
1619
/**
1720
* Auxiliary function to retry AWS SDK calls when a throttling error occurs.
1821
*/
@@ -21,8 +24,8 @@ export function throttlingBackOff<T>(
2124
options?: Partial<Omit<IBackOffOptions, 'retry'>>,
2225
): Promise<T> {
2326
return backOff(request, {
24-
startingDelay: 150,
25-
numOfAttempts: 7,
27+
startingDelay,
28+
numOfAttempts: numberOfRetries,
2629
jitter: 'full',
2730
retry: isThrottlingError,
2831
...options,
@@ -32,45 +35,47 @@ export function throttlingBackOff<T>(
3235
export const isThrottlingError = (
3336
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/explicit-module-boundary-types
3437
e: any,
35-
): boolean =>
36-
e.retryable === true ||
37-
// SDKv2 Error Structure
38-
e.code === 'ConcurrentModificationException' || // Retry for AWS Organizations
39-
e.code === 'InsufficientDeliveryPolicyException' || // Retry for ConfigService
40-
e.code === 'NoAvailableDeliveryChannelException' || // Retry for ConfigService
41-
e.code === 'ConcurrentModifications' || // Retry for AssociateHostedZone
42-
e.code === 'LimitExceededException' || // Retry for SecurityHub
43-
e.code === 'OperationNotPermittedException' || // Retry for RAM
44-
e.code === 'InvalidStateException' || //retry for ServiceCatalog
45-
e.code === 'TooManyRequestsException' ||
46-
e.code === 'TooManyUpdates' ||
47-
e.code === 'Throttling' ||
48-
e.code === 'ThrottlingException' ||
49-
e.code === 'InternalErrorException' ||
50-
e.code === 'InternalException' ||
51-
e.code === 'ECONNRESET' ||
52-
e.code === 'ENOTFOUND' ||
53-
e.code === 'EPIPE' ||
54-
e.code === 'ETIMEDOUT' ||
55-
// SDKv3 Error Structure
56-
e.name === 'ConcurrentModificationException' || // Retry for AWS Organizations
57-
e.name === 'InsufficientDeliveryPolicyException' || // Retry for ConfigService
58-
e.name === 'NoAvailableDeliveryChannelException' || // Retry for ConfigService
59-
e.name === 'ConcurrentModifications' || // Retry for AssociateHostedZone
60-
e.name === 'LimitExceededException' || // Retry for SecurityHub
61-
e.name === 'OperationNotPermittedException' || // Retry for RAM
62-
e.name === 'CredentialsProviderError' || // Retry for STS
63-
e.name === 'TooManyRequestsException' ||
64-
e.name === 'TooManyUpdates' ||
65-
e.name === 'Throttling' ||
66-
e.name === 'ThrottlingException' ||
67-
e.name === 'InternalErrorException' ||
68-
e.name === 'InternalException' ||
69-
e.name === 'ECONNRESET' ||
70-
e.name === 'EPIPE' ||
71-
e.name === 'ENOTFOUND' ||
72-
e.name === 'ETIMEDOUT';
73-
38+
): boolean => {
39+
return (
40+
e.retryable === true ||
41+
// SDKv2 Error Structure
42+
e.code === 'ConcurrentModificationException' || // Retry for AWS Organizations
43+
e.code === 'InsufficientDeliveryPolicyException' || // Retry for ConfigService
44+
e.code === 'NoAvailableDeliveryChannelException' || // Retry for ConfigService
45+
e.code === 'ConcurrentModifications' || // Retry for AssociateHostedZone
46+
e.code === 'LimitExceededException' || // Retry for SecurityHub
47+
e.code === 'OperationNotPermittedException' || // Retry for RAM
48+
e.code === 'InvalidStateException' || //retry for ServiceCatalog
49+
e.code === 'TooManyRequestsException' ||
50+
e.code === 'TooManyUpdates' ||
51+
e.code === 'Throttling' ||
52+
e.code === 'ThrottlingException' ||
53+
e.code === 'InternalErrorException' ||
54+
e.code === 'InternalException' ||
55+
e.code === 'ECONNRESET' ||
56+
e.code === 'ENOTFOUND' ||
57+
e.code === 'EPIPE' ||
58+
e.code === 'ETIMEDOUT' ||
59+
// SDKv3 Error Structure
60+
e.name === 'ConcurrentModificationException' || // Retry for AWS Organizations
61+
e.name === 'InsufficientDeliveryPolicyException' || // Retry for ConfigService
62+
e.name === 'NoAvailableDeliveryChannelException' || // Retry for ConfigService
63+
e.name === 'ConcurrentModifications' || // Retry for AssociateHostedZone
64+
e.name === 'LimitExceededException' || // Retry for SecurityHub
65+
e.name === 'OperationNotPermittedException' || // Retry for RAM
66+
e.name === 'CredentialsProviderError' || // Retry for STS
67+
e.name === 'TooManyRequestsException' ||
68+
e.name === 'TooManyUpdates' ||
69+
e.name === 'Throttling' ||
70+
e.name === 'ThrottlingException' ||
71+
e.name === 'InternalErrorException' ||
72+
e.name === 'InternalException' ||
73+
e.name === 'ECONNRESET' ||
74+
e.name === 'EPIPE' ||
75+
e.name === 'ENOTFOUND' ||
76+
e.name === 'ETIMEDOUT'
77+
);
78+
};
7479
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7580
export async function delay(ms: number): Promise<any> {
7681
return new Promise(resolve => setTimeout(resolve, ms));

0 commit comments

Comments
 (0)