From a92a0f6f1ac173755cc6627bc79adf8b5ba4cd0f Mon Sep 17 00:00:00 2001 From: SukkaW Date: Thu, 10 Oct 2024 13:58:56 +0800 Subject: [PATCH] Refactor: simplify parallel cached fetching --- Build/lib/cache-filesystem.ts | 60 ++++++++++------------------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/Build/lib/cache-filesystem.ts b/Build/lib/cache-filesystem.ts index cb8e90bd..23416c69 100644 --- a/Build/lib/cache-filesystem.ts +++ b/Build/lib/cache-filesystem.ts @@ -305,49 +305,19 @@ export class Cache { const previouslyCached = this.get(cachedKey); - const primaryETag = this.get(getETagKey(primaryUrl)); - const fetchMainPromise = fetchWithRetry( - primaryUrl, - { - signal: controller.signal, - ...defaultRequestInit, - headers: (typeof primaryETag === 'string' && primaryETag.length > 0) - ? mergeHeaders( - defaultRequestInit.headers, - { 'If-None-Match': primaryETag } - ) - : defaultRequestInit.headers - } - ).then(r => { - if (r.headers.has('etag')) { - this.set(getETagKey(primaryUrl), r.headers.get('etag')!, TTL.ONE_WEEK_STATIC); - - // If we do not have a cached value, we ignore 304 - if (r.status === 304 && typeof previouslyCached === 'string') { - controller.abort(); - throw new Custom304NotModifiedError(primaryUrl, previouslyCached); - } - } else if (!primaryETag && typeof previouslyCached === 'string') { - throw new CustomNoETagFallbackError(previouslyCached); - } - - return r.text(); - }).then(text => { - controller.abort(); - return text; - }); - const createFetchFallbackPromise = async (url: string, index: number) => { // Most assets can be downloaded within 250ms. To avoid wasting bandwidth, we will wait for 500ms before downloading from the fallback URL. - try { - await sleepWithAbort(300 + (index + 1) * 10, controller.signal); - } catch { - console.log(picocolors.gray('[fetch cancelled early]'), picocolors.gray(url)); - throw new CustomAbortError(); - } - if (controller.signal.aborted) { - console.log(picocolors.gray('[fetch cancelled]'), picocolors.gray(url)); - throw new CustomAbortError(); + if (index > 0) { + try { + await sleepWithAbort(300 + (index + 1) * 10, controller.signal); + } catch { + console.log(picocolors.gray('[fetch cancelled early]'), picocolors.gray(url)); + throw new CustomAbortError(); + } + if (controller.signal.aborted) { + console.log(picocolors.gray('[fetch cancelled]'), picocolors.gray(url)); + throw new CustomAbortError(); + } } const etag = this.get(getETagKey(url)); @@ -373,11 +343,13 @@ export class Cache { controller.abort(); throw new Custom304NotModifiedError(url, previouslyCached); } - } else if (!primaryETag && typeof previouslyCached === 'string') { + } else if (!this.get(getETagKey(primaryUrl)) && typeof previouslyCached === 'string') { controller.abort(); throw new CustomNoETagFallbackError(previouslyCached); } + // either no etag and not cached + // or has etag but not 304 const text = await res.text(); controller.abort(); return text; @@ -385,7 +357,7 @@ export class Cache { try { const text = await Promise.any([ - fetchMainPromise, + createFetchFallbackPromise(primaryUrl, -1), ...mirrorUrls.map(createFetchFallbackPromise) ]); @@ -405,7 +377,7 @@ export class Cache { if (error instanceof Custom304NotModifiedError) { console.log(picocolors.green('[cache] http 304'), picocolors.gray(primaryUrl)); this.updateTtl(cachedKey, TTL.ONE_WEEK_STATIC); - return deserializer(previouslyCached); + return deserializer(error.data); } if (error instanceof CustomNoETagFallbackError) { console.log(picocolors.green('[cache] hit'), picocolors.gray(primaryUrl));