@alwaysmeticulous/remote-replay-launcher 2.276.2 → 2.276.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/asset-upload-utils.js +23 -11
- package/dist/asset-upload-utils.js.map +1 -1
- package/dist/upload-utils/__tests__/retry-transient-s3-errors.spec.d.ts +1 -0
- package/dist/upload-utils/__tests__/retry-transient-s3-errors.spec.js +158 -0
- package/dist/upload-utils/__tests__/retry-transient-s3-errors.spec.js.map +1 -0
- package/dist/upload-utils/retry-transient-s3-errors.d.ts +13 -0
- package/dist/upload-utils/retry-transient-s3-errors.js +73 -0
- package/dist/upload-utils/retry-transient-s3-errors.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="466ef336-8c5d-5cbf-8715-0e3da67ebbc2")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
5
|
if (k2 === undefined) k2 = k;
|
|
@@ -46,6 +46,7 @@ const common_1 = require("@alwaysmeticulous/common");
|
|
|
46
46
|
const Sentry = __importStar(require("@sentry/node"));
|
|
47
47
|
const poll_for_base_test_run_1 = require("./poll-for-base-test-run");
|
|
48
48
|
const multipart_compressing_uploader_1 = require("./upload-utils/multipart-compressing-uploader");
|
|
49
|
+
const retry_transient_s3_errors_1 = require("./upload-utils/retry-transient-s3-errors");
|
|
49
50
|
/**
|
|
50
51
|
* Uploads assets from a directory and returns the upload ID and client for further operations
|
|
51
52
|
*/
|
|
@@ -158,6 +159,18 @@ const uploadAssetsStreaming = async ({ client, folderPath, commitSha, baseSha, g
|
|
|
158
159
|
};
|
|
159
160
|
};
|
|
160
161
|
const uploadBufferToSignedUrl = async (signedUrl, buffer, options) => {
|
|
162
|
+
return (0, retry_transient_s3_errors_1.retryTransientS3Errors)(() => putBufferToSignedUrl(signedUrl, buffer, options), { onRetry: logTransientUploadRetry });
|
|
163
|
+
};
|
|
164
|
+
const logTransientUploadRetry = (attempt, error) => {
|
|
165
|
+
const logger = (0, common_1.initLogger)();
|
|
166
|
+
const reason = error instanceof retry_transient_s3_errors_1.S3UploadError
|
|
167
|
+
? `HTTP ${error.statusCode}`
|
|
168
|
+
: error instanceof Error
|
|
169
|
+
? error.message
|
|
170
|
+
: String(error);
|
|
171
|
+
logger.warn(`Transient upload error on attempt ${attempt} (${reason}); will retry...`);
|
|
172
|
+
};
|
|
173
|
+
const putBufferToSignedUrl = async (signedUrl, buffer, options) => {
|
|
161
174
|
return new Promise((resolve, reject) => {
|
|
162
175
|
const headers = {
|
|
163
176
|
"Content-Length": buffer.length,
|
|
@@ -179,8 +192,7 @@ const uploadBufferToSignedUrl = async (signedUrl, buffer, options) => {
|
|
|
179
192
|
resolve(response.headers["etag"] ?? "");
|
|
180
193
|
}
|
|
181
194
|
else {
|
|
182
|
-
|
|
183
|
-
reject(new Error(errorMessage));
|
|
195
|
+
reject(new retry_transient_s3_errors_1.S3UploadError(response.statusCode ?? 0, responseData));
|
|
184
196
|
}
|
|
185
197
|
});
|
|
186
198
|
});
|
|
@@ -256,7 +268,6 @@ const uploadAssetsFromZip = async ({ apiToken: apiToken_, zipPath, commitSha, ba
|
|
|
256
268
|
};
|
|
257
269
|
exports.uploadAssetsFromZip = uploadAssetsFromZip;
|
|
258
270
|
const uploadFileToSignedUrl = async (filePath, signedUrl, expectedFileSize) => {
|
|
259
|
-
const fileStream = (0, fs_1.createReadStream)(filePath);
|
|
260
271
|
const logger = (0, common_1.initLogger)();
|
|
261
272
|
const fileStats = await (0, promises_1.stat)(filePath);
|
|
262
273
|
const fileSize = fileStats.size;
|
|
@@ -264,7 +275,13 @@ const uploadFileToSignedUrl = async (filePath, signedUrl, expectedFileSize) => {
|
|
|
264
275
|
throw new Error(`File size mismatch: expected ${expectedFileSize} bytes, got ${fileSize} bytes`);
|
|
265
276
|
}
|
|
266
277
|
logger.info(`Uploading deployment assets (${fileSize} bytes)...`);
|
|
278
|
+
await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(() => putFileToSignedUrl(filePath, signedUrl, fileSize), { onRetry: logTransientUploadRetry });
|
|
279
|
+
logger.info("Successfully uploaded deployment assets");
|
|
280
|
+
};
|
|
281
|
+
const putFileToSignedUrl = async (filePath, signedUrl, fileSize) => {
|
|
267
282
|
return new Promise((resolve, reject) => {
|
|
283
|
+
// A new read stream is required on every attempt — streams cannot be replayed.
|
|
284
|
+
const fileStream = (0, fs_1.createReadStream)(filePath);
|
|
268
285
|
const req = (0, https_1.request)(signedUrl, {
|
|
269
286
|
agent: (0, client_1.getProxyAgent)(),
|
|
270
287
|
method: "PUT",
|
|
@@ -279,22 +296,17 @@ const uploadFileToSignedUrl = async (filePath, signedUrl, expectedFileSize) => {
|
|
|
279
296
|
});
|
|
280
297
|
response.on("end", () => {
|
|
281
298
|
if (response.statusCode === 200) {
|
|
282
|
-
logger.info("Successfully uploaded deployment assets");
|
|
283
299
|
resolve();
|
|
284
300
|
}
|
|
285
301
|
else {
|
|
286
|
-
|
|
287
|
-
logger.error(errorMessage);
|
|
288
|
-
reject(new Error(errorMessage));
|
|
302
|
+
reject(new retry_transient_s3_errors_1.S3UploadError(response.statusCode ?? 0, responseData));
|
|
289
303
|
}
|
|
290
304
|
});
|
|
291
305
|
});
|
|
292
306
|
req.on("error", (error) => {
|
|
293
|
-
logger.error(`Upload request error: ${error.message}`);
|
|
294
307
|
reject(error);
|
|
295
308
|
});
|
|
296
309
|
fileStream.on("error", (error) => {
|
|
297
|
-
logger.error(`File stream error: ${error.message}`);
|
|
298
310
|
req.destroy(error);
|
|
299
311
|
reject(error);
|
|
300
312
|
});
|
|
@@ -302,4 +314,4 @@ const uploadFileToSignedUrl = async (filePath, signedUrl, expectedFileSize) => {
|
|
|
302
314
|
});
|
|
303
315
|
};
|
|
304
316
|
//# sourceMappingURL=asset-upload-utils.js.map
|
|
305
|
-
//# debugId=
|
|
317
|
+
//# debugId=466ef336-8c5d-5cbf-8715-0e3da67ebbc2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-upload-utils.js","sources":["../src/asset-upload-utils.ts"],"sourceRoot":"","names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2BAAkD;AAClD,0CAA2C;AAE3C,iCAAgD;AAChD,+BAAqC;AAErC,qDASkC;AAClC,uGAAmG;AACnG,qDAAsD;AACtD,qDAAuC;AACvC,qEAAiE;AACjE,kGAAyH;
|
|
1
|
+
{"version":3,"file":"asset-upload-utils.js","sources":["../src/asset-upload-utils.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"466ef336-8c5d-5cbf-8715-0e3da67ebbc2"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a73ce9a9-4697-57d5-aac0-a219fb1a0c68")}catch(e){}}();
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const vitest_1 = require("vitest");
|
|
6
|
+
const retry_transient_s3_errors_1 = require("../retry-transient-s3-errors");
|
|
7
|
+
(0, vitest_1.describe)("retryTransientS3Errors", () => {
|
|
8
|
+
const noSleep = async () => { };
|
|
9
|
+
(0, vitest_1.it)("returns the value when the operation succeeds on the first attempt", async () => {
|
|
10
|
+
const operation = vitest_1.vi.fn(async () => "ok");
|
|
11
|
+
const result = await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep });
|
|
12
|
+
(0, vitest_1.expect)(result).toBe("ok");
|
|
13
|
+
(0, vitest_1.expect)(operation).toHaveBeenCalledTimes(1);
|
|
14
|
+
});
|
|
15
|
+
(0, vitest_1.it)("retries on S3 503 SlowDown and eventually succeeds", async () => {
|
|
16
|
+
let attempts = 0;
|
|
17
|
+
const operation = async () => {
|
|
18
|
+
attempts++;
|
|
19
|
+
if (attempts < 3) {
|
|
20
|
+
throw new retry_transient_s3_errors_1.S3UploadError(503, "<Code>SlowDown</Code>");
|
|
21
|
+
}
|
|
22
|
+
return "ok";
|
|
23
|
+
};
|
|
24
|
+
const result = await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep });
|
|
25
|
+
(0, vitest_1.expect)(result).toBe("ok");
|
|
26
|
+
(0, vitest_1.expect)(attempts).toBe(3);
|
|
27
|
+
});
|
|
28
|
+
(0, vitest_1.it)("retries on S3 500 InternalError", async () => {
|
|
29
|
+
let attempts = 0;
|
|
30
|
+
const operation = async () => {
|
|
31
|
+
attempts++;
|
|
32
|
+
if (attempts < 2) {
|
|
33
|
+
throw new retry_transient_s3_errors_1.S3UploadError(500, "<Code>InternalError</Code>");
|
|
34
|
+
}
|
|
35
|
+
return "ok";
|
|
36
|
+
};
|
|
37
|
+
const result = await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep });
|
|
38
|
+
(0, vitest_1.expect)(result).toBe("ok");
|
|
39
|
+
(0, vitest_1.expect)(attempts).toBe(2);
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.it)("retries on 429 Too Many Requests", async () => {
|
|
42
|
+
let attempts = 0;
|
|
43
|
+
const operation = async () => {
|
|
44
|
+
attempts++;
|
|
45
|
+
if (attempts < 2) {
|
|
46
|
+
throw new retry_transient_s3_errors_1.S3UploadError(429, "");
|
|
47
|
+
}
|
|
48
|
+
return "ok";
|
|
49
|
+
};
|
|
50
|
+
const result = await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep });
|
|
51
|
+
(0, vitest_1.expect)(attempts).toBe(2);
|
|
52
|
+
(0, vitest_1.expect)(result).toBe("ok");
|
|
53
|
+
});
|
|
54
|
+
(0, vitest_1.it)("retries on transient network errors like ECONNRESET", async () => {
|
|
55
|
+
let attempts = 0;
|
|
56
|
+
const operation = async () => {
|
|
57
|
+
attempts++;
|
|
58
|
+
if (attempts < 2) {
|
|
59
|
+
const err = new Error("socket hang up");
|
|
60
|
+
err.code = "ECONNRESET";
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
return "ok";
|
|
64
|
+
};
|
|
65
|
+
const result = await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep });
|
|
66
|
+
(0, vitest_1.expect)(attempts).toBe(2);
|
|
67
|
+
(0, vitest_1.expect)(result).toBe("ok");
|
|
68
|
+
});
|
|
69
|
+
(0, vitest_1.it)("does not retry on 4xx client errors (e.g. 403 Forbidden)", async () => {
|
|
70
|
+
const operation = vitest_1.vi.fn(async () => {
|
|
71
|
+
throw new retry_transient_s3_errors_1.S3UploadError(403, "<Code>AccessDenied</Code>");
|
|
72
|
+
});
|
|
73
|
+
await (0, vitest_1.expect)((0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep })).rejects.toBeInstanceOf(retry_transient_s3_errors_1.S3UploadError);
|
|
74
|
+
(0, vitest_1.expect)(operation).toHaveBeenCalledTimes(1);
|
|
75
|
+
});
|
|
76
|
+
(0, vitest_1.it)("does not retry on arbitrary non-transient errors", async () => {
|
|
77
|
+
const operation = vitest_1.vi.fn(async () => {
|
|
78
|
+
throw new Error("something unrelated");
|
|
79
|
+
});
|
|
80
|
+
await (0, vitest_1.expect)((0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, { sleep: noSleep })).rejects.toThrow("something unrelated");
|
|
81
|
+
(0, vitest_1.expect)(operation).toHaveBeenCalledTimes(1);
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.it)("throws the last error after exhausting retries", async () => {
|
|
84
|
+
const operation = vitest_1.vi.fn(async () => {
|
|
85
|
+
throw new retry_transient_s3_errors_1.S3UploadError(503, "<Code>SlowDown</Code>");
|
|
86
|
+
});
|
|
87
|
+
await (0, vitest_1.expect)((0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, {
|
|
88
|
+
sleep: noSleep,
|
|
89
|
+
maxAttempts: 3,
|
|
90
|
+
})).rejects.toBeInstanceOf(retry_transient_s3_errors_1.S3UploadError);
|
|
91
|
+
(0, vitest_1.expect)(operation).toHaveBeenCalledTimes(3);
|
|
92
|
+
});
|
|
93
|
+
(0, vitest_1.it)("applies exponential backoff with jitter between retries", async () => {
|
|
94
|
+
const delays = [];
|
|
95
|
+
const sleep = async (ms) => {
|
|
96
|
+
delays.push(ms);
|
|
97
|
+
};
|
|
98
|
+
let attempts = 0;
|
|
99
|
+
const operation = async () => {
|
|
100
|
+
attempts++;
|
|
101
|
+
if (attempts < 4) {
|
|
102
|
+
throw new retry_transient_s3_errors_1.S3UploadError(503, "");
|
|
103
|
+
}
|
|
104
|
+
return "ok";
|
|
105
|
+
};
|
|
106
|
+
// Make jitter deterministic
|
|
107
|
+
const randomSpy = vitest_1.vi.spyOn(Math, "random").mockReturnValue(0.5);
|
|
108
|
+
try {
|
|
109
|
+
await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, {
|
|
110
|
+
sleep,
|
|
111
|
+
baseDelayMs: 100,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
randomSpy.mockRestore();
|
|
116
|
+
}
|
|
117
|
+
// With Math.random() = 0.5, jitter multiplier = 0.5 + 0.5 = 1.0
|
|
118
|
+
// So delays should be: 100, 200, 400
|
|
119
|
+
(0, vitest_1.expect)(delays).toEqual([100, 200, 400]);
|
|
120
|
+
});
|
|
121
|
+
(0, vitest_1.it)("invokes onRetry with attempt number and error before sleeping", async () => {
|
|
122
|
+
const onRetry = vitest_1.vi.fn();
|
|
123
|
+
let attempts = 0;
|
|
124
|
+
const operation = async () => {
|
|
125
|
+
attempts++;
|
|
126
|
+
if (attempts < 3) {
|
|
127
|
+
throw new retry_transient_s3_errors_1.S3UploadError(503, "");
|
|
128
|
+
}
|
|
129
|
+
return "ok";
|
|
130
|
+
};
|
|
131
|
+
await (0, retry_transient_s3_errors_1.retryTransientS3Errors)(operation, {
|
|
132
|
+
sleep: noSleep,
|
|
133
|
+
onRetry,
|
|
134
|
+
});
|
|
135
|
+
(0, vitest_1.expect)(onRetry).toHaveBeenCalledTimes(2);
|
|
136
|
+
(0, vitest_1.expect)(onRetry).toHaveBeenNthCalledWith(1, 1, vitest_1.expect.any(retry_transient_s3_errors_1.S3UploadError));
|
|
137
|
+
(0, vitest_1.expect)(onRetry).toHaveBeenNthCalledWith(2, 2, vitest_1.expect.any(retry_transient_s3_errors_1.S3UploadError));
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.describe)("S3UploadError", () => {
|
|
141
|
+
(0, vitest_1.it)("exposes the status code and response body", () => {
|
|
142
|
+
const error = new retry_transient_s3_errors_1.S3UploadError(503, "<Code>SlowDown</Code>");
|
|
143
|
+
(0, vitest_1.expect)(error.statusCode).toBe(503);
|
|
144
|
+
(0, vitest_1.expect)(error.responseBody).toBe("<Code>SlowDown</Code>");
|
|
145
|
+
});
|
|
146
|
+
(0, vitest_1.it)("formats the message so existing logs remain readable", () => {
|
|
147
|
+
const error = new retry_transient_s3_errors_1.S3UploadError(503, "<Code>SlowDown</Code>");
|
|
148
|
+
(0, vitest_1.expect)(error.message).toContain("Failed to upload!");
|
|
149
|
+
(0, vitest_1.expect)(error.message).toContain("Status 503");
|
|
150
|
+
(0, vitest_1.expect)(error.message).toContain("<Code>SlowDown</Code>");
|
|
151
|
+
});
|
|
152
|
+
(0, vitest_1.it)("is an instance of Error", () => {
|
|
153
|
+
const error = new retry_transient_s3_errors_1.S3UploadError(500, "");
|
|
154
|
+
(0, vitest_1.expect)(error).toBeInstanceOf(Error);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=retry-transient-s3-errors.spec.js.map
|
|
158
|
+
//# debugId=a73ce9a9-4697-57d5-aac0-a219fb1a0c68
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-transient-s3-errors.spec.js","sources":["../../../src/upload-utils/__tests__/retry-transient-s3-errors.spec.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"a73ce9a9-4697-57d5-aac0-a219fb1a0c68"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class S3UploadError extends Error {
|
|
2
|
+
readonly statusCode: number;
|
|
3
|
+
readonly responseBody: string;
|
|
4
|
+
constructor(statusCode: number, responseBody: string);
|
|
5
|
+
}
|
|
6
|
+
export declare const isTransientS3Error: (error: unknown) => boolean;
|
|
7
|
+
export interface RetryTransientS3ErrorsOptions {
|
|
8
|
+
maxAttempts?: number;
|
|
9
|
+
baseDelayMs?: number;
|
|
10
|
+
onRetry?: (attempt: number, error: unknown) => void;
|
|
11
|
+
sleep?: (ms: number) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare const retryTransientS3Errors: <T>(operation: () => Promise<T>, options?: RetryTransientS3ErrorsOptions) => Promise<T>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="db082a63-d2bc-51f1-bac5-ca3b0f947874")}catch(e){}}();
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.retryTransientS3Errors = exports.isTransientS3Error = exports.S3UploadError = void 0;
|
|
6
|
+
class S3UploadError extends Error {
|
|
7
|
+
statusCode;
|
|
8
|
+
responseBody;
|
|
9
|
+
constructor(statusCode, responseBody) {
|
|
10
|
+
super(`Failed to upload!\nStatus ${statusCode}.\nResponse:\n${responseBody}`);
|
|
11
|
+
this.name = "S3UploadError";
|
|
12
|
+
this.statusCode = statusCode;
|
|
13
|
+
this.responseBody = responseBody;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.S3UploadError = S3UploadError;
|
|
17
|
+
const TRANSIENT_STATUS_CODES = new Set([429, 500, 502, 503, 504]);
|
|
18
|
+
// Node networking errors that are safe to retry. S3 occasionally resets
|
|
19
|
+
// connections under load; these show up here rather than as HTTP errors.
|
|
20
|
+
// Excludes ECONNREFUSED and ENOTFOUND because those typically indicate
|
|
21
|
+
// misconfiguration rather than transient failures (EAI_AGAIN covers the
|
|
22
|
+
// transient-DNS case).
|
|
23
|
+
const TRANSIENT_NETWORK_ERROR_CODES = new Set([
|
|
24
|
+
"ECONNRESET",
|
|
25
|
+
"ETIMEDOUT",
|
|
26
|
+
"ECONNABORTED",
|
|
27
|
+
"EAI_AGAIN",
|
|
28
|
+
"EPIPE",
|
|
29
|
+
]);
|
|
30
|
+
const isTransientS3Error = (error) => {
|
|
31
|
+
if (error instanceof S3UploadError) {
|
|
32
|
+
return TRANSIENT_STATUS_CODES.has(error.statusCode);
|
|
33
|
+
}
|
|
34
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
35
|
+
const code = error.code;
|
|
36
|
+
if (typeof code === "string" && TRANSIENT_NETWORK_ERROR_CODES.has(code)) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
42
|
+
exports.isTransientS3Error = isTransientS3Error;
|
|
43
|
+
const DEFAULT_MAX_ATTEMPTS = 5;
|
|
44
|
+
const DEFAULT_BASE_DELAY_MS = 200;
|
|
45
|
+
const MAX_DELAY_MS = 30_000;
|
|
46
|
+
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
47
|
+
const retryTransientS3Errors = async (operation, options = {}) => {
|
|
48
|
+
const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
49
|
+
const baseDelayMs = options.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
|
|
50
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
51
|
+
let lastError;
|
|
52
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
53
|
+
try {
|
|
54
|
+
return await operation();
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
lastError = error;
|
|
58
|
+
if (!(0, exports.isTransientS3Error)(error) || attempt === maxAttempts) {
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
// Exponential backoff with a jitter multiplier in [0.5, 1.5), capped
|
|
62
|
+
// to bound worst-case sleep when callers pass a large baseDelayMs.
|
|
63
|
+
const jitter = 0.5 + Math.random();
|
|
64
|
+
const delayMs = Math.min(Math.floor(baseDelayMs * Math.pow(2, attempt - 1) * jitter), MAX_DELAY_MS);
|
|
65
|
+
options.onRetry?.(attempt, error);
|
|
66
|
+
await sleep(delayMs);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
throw lastError;
|
|
70
|
+
};
|
|
71
|
+
exports.retryTransientS3Errors = retryTransientS3Errors;
|
|
72
|
+
//# sourceMappingURL=retry-transient-s3-errors.js.map
|
|
73
|
+
//# debugId=db082a63-d2bc-51f1-bac5-ca3b0f947874
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-transient-s3-errors.js","sources":["../../src/upload-utils/retry-transient-s3-errors.ts"],"sourceRoot":"","names":[],"mappings":"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","debugId":"db082a63-d2bc-51f1-bac5-ca3b0f947874"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwaysmeticulous/remote-replay-launcher",
|
|
3
|
-
"version": "2.276.
|
|
3
|
+
"version": "2.276.3",
|
|
4
4
|
"description": "Executes a remote replay on Meticulous' infrastructure",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"bugs": {
|
|
54
54
|
"url": "https://github.com/alwaysmeticulous/meticulous-sdk/issues"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "5d98d02aac2c8b990355cfebe7a3ead8fbff52e9"
|
|
57
57
|
}
|