Skip to content

Commit 77bd9a1

Browse files
authored
Remove now-unused asset preservation cache v1 from Pages (#7544)
1 parent fb30983 commit 77bd9a1

File tree

3 files changed

+15
-112
lines changed

3 files changed

+15
-112
lines changed

.changeset/green-socks-trade.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/pages-shared": patch
3+
---
4+
5+
chore: Remove now-unused asset preservation cache (v1)

packages/pages-shared/__tests__/asset-server/handler.test.ts

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -611,90 +611,6 @@ describe("asset-server handler", () => {
611611
}
612612
`);
613613
});
614-
615-
test("preservationCacheV1 (fallback)", async () => {
616-
vi.setSystemTime(new Date("2024-05-09")); // 1 day before fallback is disabled
617-
618-
const deploymentId = "deployment-" + Math.random();
619-
const metadata = createMetadataObject({ deploymentId }) as Metadata;
620-
const { caches } = createCacheStorage();
621-
622-
const preservationCacheV1 = await caches.open("assetPreservationCache");
623-
624-
// Write a response to the V1 cache and make sure it persists
625-
await preservationCacheV1.put(
626-
"https://example.com/foo",
627-
new Response("preserved in V1 cache!", {
628-
headers: {
629-
"Cache-Control": "public, max-age=300",
630-
},
631-
})
632-
);
633-
634-
const preservationRes = await preservationCacheV1.match(
635-
"https://example.com/foo"
636-
);
637-
638-
if (!preservationRes) {
639-
throw new Error(
640-
"Did not match preservation cache on https://example.com/foo"
641-
);
642-
}
643-
644-
expect(await preservationRes.text()).toMatchInlineSnapshot(
645-
`"preserved in V1 cache!"`
646-
);
647-
648-
// Delete the asset from the manifest and ensure it's served from V1 preservation cache
649-
const findAssetEntryForPath = async (_path: string) => {
650-
return null;
651-
};
652-
const { response, spies } = await getTestResponse({
653-
request: new Request("https://example.com/foo"),
654-
metadata,
655-
findAssetEntryForPath,
656-
caches,
657-
fetchAsset: () =>
658-
Promise.resolve(Object.assign(new Response("hello world!"))),
659-
});
660-
expect(response.status).toBe(200);
661-
expect(await response.text()).toMatchInlineSnapshot(
662-
`"preserved in V1 cache!"`
663-
);
664-
expect(Object.fromEntries(response.headers)).toMatchInlineSnapshot(`
665-
{
666-
"access-control-allow-origin": "*",
667-
"cache-control": "public, max-age=300",
668-
"cf-cache-status": "HIT",
669-
"content-type": "text/plain;charset=UTF-8",
670-
"referrer-policy": "strict-origin-when-cross-origin",
671-
"x-content-type-options": "nosniff",
672-
}
673-
`);
674-
// No cache or early hints writes
675-
expect(spies.waitUntil.length).toBe(0);
676-
677-
// Should disable fallback starting may 10th
678-
vi.setSystemTime(new Date("2024-05-10"));
679-
const { response: response2, spies: spies2 } = await getTestResponse({
680-
request: new Request("https://example.com/foo"),
681-
metadata,
682-
findAssetEntryForPath,
683-
caches,
684-
fetchAsset: () =>
685-
Promise.resolve(Object.assign(new Response("hello world!"))),
686-
});
687-
expect(response2.status).toBe(404);
688-
expect(Object.fromEntries(response2.headers)).toMatchInlineSnapshot(`
689-
{
690-
"access-control-allow-origin": "*",
691-
"cache-control": "no-store",
692-
"referrer-policy": "strict-origin-when-cross-origin",
693-
}
694-
`);
695-
// No cache or early hints writes
696-
expect(spies2.waitUntil.length).toBe(0);
697-
});
698614
});
699615

700616
describe("isPreservationCacheResponseExpiring()", async () => {

packages/pages-shared/asset-server/handler.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@ type BodyEncoding = "manual" | "automatic";
2525
// Before serving a 404, we check the cache to see if we've served this asset recently
2626
// and if so, serve it from the cache instead of responding with a 404.
2727
// This gives a bit of a grace period between deployments for any clients browsing the old deployment.
28-
export const ASSET_PRESERVATION_CACHE_V1 = "assetPreservationCache";
29-
// V2 stores the content hash instead of the asset.
30-
// TODO: Remove V1 once we've fully migrated to V2
31-
export const ASSET_PRESERVATION_CACHE_V2 = "assetPreservationCacheV2";
28+
// Only the content hash is actually stored in the body.
29+
export const ASSET_PRESERVATION_CACHE = "assetPreservationCacheV2";
3230
const CACHE_CONTROL_PRESERVATION = "public, s-maxage=604800"; // 1 week
3331

3432
/** The preservation cache should be periodically
@@ -576,14 +574,14 @@ export async function generateHandler<
576574
waitUntil(
577575
(async () => {
578576
try {
579-
const assetPreservationCacheV2 = await caches.open(
580-
ASSET_PRESERVATION_CACHE_V2
577+
const assetPreservationCache = await caches.open(
578+
ASSET_PRESERVATION_CACHE
581579
);
582580

583581
// Check if the asset has changed since last written to cache
584582
// or if the cached entry is getting too old and should have
585583
// it's expiration reset.
586-
const match = await assetPreservationCacheV2.match(request);
584+
const match = await assetPreservationCache.match(request);
587585
if (
588586
!match ||
589587
assetKey !== (await match.text()) ||
@@ -599,7 +597,7 @@ export async function generateHandler<
599597
);
600598
preservedResponse.headers.set("x-robots-tag", "noindex");
601599

602-
await assetPreservationCacheV2.put(
600+
await assetPreservationCache.put(
603601
request.url,
604602
preservedResponse
605603
);
@@ -637,30 +635,13 @@ export async function generateHandler<
637635
async function notFound(): Promise<Response> {
638636
if (caches) {
639637
try {
640-
const assetPreservationCacheV2 = await caches.open(
641-
ASSET_PRESERVATION_CACHE_V2
638+
const assetPreservationCache = await caches.open(
639+
ASSET_PRESERVATION_CACHE
642640
);
643-
let preservedResponse = await assetPreservationCacheV2.match(
641+
const preservedResponse = await assetPreservationCache.match(
644642
request.url
645643
);
646644

647-
// Continue serving from V1 preservation cache for some time to
648-
// prevent 404s during the migration to V2
649-
const cutoffDate = new Date("2024-05-17");
650-
if (!preservedResponse && Date.now() < cutoffDate.getTime()) {
651-
const assetPreservationCacheV1 = await caches.open(
652-
ASSET_PRESERVATION_CACHE_V1
653-
);
654-
preservedResponse = await assetPreservationCacheV1.match(request.url);
655-
if (preservedResponse) {
656-
// V1 cache contains full response bodies so we return it directly
657-
if (setMetrics) {
658-
setMetrics({ preservationCacheResult: "checked-hit" });
659-
}
660-
return preservedResponse;
661-
}
662-
}
663-
664645
// V2 cache only contains the asset key, rather than the asset body:
665646
if (preservedResponse) {
666647
if (setMetrics) {
@@ -674,6 +655,7 @@ export async function generateHandler<
674655
}
675656
if (assetKey) {
676657
const asset = await fetchAsset(assetKey);
658+
677659
if (asset) {
678660
// We know the asset hasn't changed, so use the cached headers.
679661
return new Response(asset.body, preservedResponse);

0 commit comments

Comments
 (0)