Skip to content

Commit 785dc52

Browse files
authored
Extra timeout in CDN Worker's fetchText function (#5532)
1 parent df57e60 commit 785dc52

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

packages/services/cdn-worker/src/handler.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -274,22 +274,13 @@ export function createRequestHandler(deps: RequestHandlerDependencies) {
274274
analytics.track({ type: 'artifact', value: artifactType, version: 'v0' }, targetId);
275275

276276
const kvStorageKey = `target:${targetId}:${storageKeyType}`;
277-
const rawValueAction = await deps
278-
.getArtifactAction(targetId, null, storageKeyType, null)
279-
.catch(() => {
280-
// Do an extra attempt to read the value from the store.
281-
// If we see that a single retry does not help, we should do a proper retry logic here.
282-
// Why not now? Because we do have a new implementation that is based on R2 storage and this change is simple enough.
283-
return deps.getArtifactAction(targetId, null, storageKeyType, null);
284-
});
277+
const rawValueAction = await deps.getArtifactAction(targetId, null, storageKeyType, null);
285278

286279
if (rawValueAction.type === 'redirect') {
287280
// We're using here a private location, because the public S3 endpoint may differ from the internal S3 endpoint. E.g. within a docker network,
288281
// and we're fetching the artifact from within the private network.
289282
// If they are the same, private and public locations will be the same.
290-
const rawValue = await deps
291-
.fetchText(rawValueAction.location.private)
292-
.catch(() => deps.fetchText(rawValueAction.location.private));
283+
const rawValue = await deps.fetchText(rawValueAction.location.private);
293284

294285
const etag = await createETag(`${kvStorageKey}|${rawValue}`);
295286
const ifNoneMatch = request.headers.get('if-none-match');

packages/services/cdn-worker/src/index.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,40 @@ const handler: ExportedHandler<Env> = {
7777
isKeyValid,
7878
analytics,
7979
async fetchText(url) {
80-
const r = await fetch(url);
80+
// Yeah, it's not globally defined, but it makes no sense to define it globally
81+
// it's only used here and it's easier to see how it's used
82+
const retries = 5;
83+
const initRetryMs = 50;
8184

82-
if (r.ok) {
83-
return r.text();
85+
for (let i = 0; i <= retries; i++) {
86+
const fetched = fetch(url, {
87+
signal: AbortSignal.timeout(5000),
88+
});
89+
90+
if (i === retries) {
91+
const res = await fetched;
92+
if (res.ok) {
93+
return res.text();
94+
}
95+
96+
throw new Error(`Failed to fetch ${url}, status: ${res.status}`);
97+
}
98+
99+
try {
100+
const res = await fetched;
101+
if (res.ok) {
102+
return res.text();
103+
}
104+
} catch (error) {
105+
// Retry also when there's an exception
106+
console.error(error);
107+
}
108+
await new Promise(resolve =>
109+
setTimeout(resolve, Math.random() * initRetryMs * Math.pow(2, i)),
110+
);
84111
}
85112

86-
throw new Error(`Failed to fetch ${url}, status: ${r.status}`);
113+
throw new Error('An unknown error occurred, ensure retries is not negative');
87114
},
88115
});
89116

0 commit comments

Comments
 (0)