Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/pages/downloads/folia.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ export const prerender = false;
import { env } from "cloudflare:workers";
import Layout from "@/layouts/Layout.astro";
import SoftwareDownloadPage from "@/components/data/SoftwareDownloadPage.svelte";
import { fetchDownloadsPageSnapshot } from "@/utils/download";
import { downloadsPageCacheTag, fetchDownloadsPageSnapshot } from "@/utils/download";
import { coordinatorStub } from "@/downloads-live";

Astro.response.headers.set("Cache-Control", "private, max-age=60");
Astro.response.headers.set("Cache-Control", "public, max-age=300, s-maxage=600, stale-while-revalidate=120");
Astro.response.headers.set("Cache-Tag", downloadsPageCacheTag("folia"));
const snapshot = await fetchDownloadsPageSnapshot("folia", env.WEBSITE_CACHE, () => coordinatorStub(env, "folia"));
---

Expand Down
5 changes: 3 additions & 2 deletions src/pages/downloads/paper.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ export const prerender = false;
import { env } from "cloudflare:workers";
import Layout from "@/layouts/Layout.astro";
import SoftwareDownloadPage from "@/components/data/SoftwareDownloadPage.svelte";
import { fetchDownloadsPageSnapshot } from "@/utils/download";
import { downloadsPageCacheTag, fetchDownloadsPageSnapshot } from "@/utils/download";
import { coordinatorStub } from "@/downloads-live";

Astro.response.headers.set("Cache-Control", "private, max-age=60");
Astro.response.headers.set("Cache-Control", "public, max-age=300, s-maxage=600, stale-while-revalidate=120");
Astro.response.headers.set("Cache-Tag", downloadsPageCacheTag("paper"));
const snapshot = await fetchDownloadsPageSnapshot("paper", env.WEBSITE_CACHE, () => coordinatorStub(env, "paper"));
---

Expand Down
5 changes: 3 additions & 2 deletions src/pages/downloads/velocity.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ export const prerender = false;
import { env } from "cloudflare:workers";
import Layout from "@/layouts/Layout.astro";
import SoftwareDownloadPage from "@/components/data/SoftwareDownloadPage.svelte";
import { fetchDownloadsPageSnapshot } from "@/utils/download";
import { downloadsPageCacheTag, fetchDownloadsPageSnapshot } from "@/utils/download";
import { coordinatorStub } from "@/downloads-live";

Astro.response.headers.set("Cache-Control", "private, max-age=60");
Astro.response.headers.set("Cache-Control", "public, max-age=300, s-maxage=600, stale-while-revalidate=120");
Astro.response.headers.set("Cache-Tag", downloadsPageCacheTag("velocity"));
const snapshot = await fetchDownloadsPageSnapshot("velocity", env.WEBSITE_CACHE, () => coordinatorStub(env, "velocity"));
---

Expand Down
5 changes: 3 additions & 2 deletions src/pages/downloads/waterfall.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ export const prerender = false;
import { env } from "cloudflare:workers";
import Layout from "@/layouts/Layout.astro";
import SoftwareDownloadPage from "@/components/data/SoftwareDownloadPage.svelte";
import { fetchDownloadsPageSnapshot } from "@/utils/download";
import { downloadsPageCacheTag, fetchDownloadsPageSnapshot } from "@/utils/download";
import { coordinatorStub } from "@/downloads-live";

Astro.response.headers.set("Cache-Control", "private, max-age=60");
Astro.response.headers.set("Cache-Control", "public, max-age=300, s-maxage=600, stale-while-revalidate=120");
Astro.response.headers.set("Cache-Tag", downloadsPageCacheTag("waterfall"));
const snapshot = await fetchDownloadsPageSnapshot("waterfall", env.WEBSITE_CACHE, () => coordinatorStub(env, "waterfall"));

const descriptionHtml = `
Expand Down
4 changes: 2 additions & 2 deletions src/pages/webhooks/fill.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { APIRoute } from "astro";
import { env } from "cloudflare:workers";
import { env, exports } from "cloudflare:workers";
import { isDownloadProjectId } from "@/utils/download";
import { requestDownloadsRefresh } from "@/downloads-live";

Expand Down Expand Up @@ -67,7 +67,7 @@ export const POST: APIRoute = async ({ request, locals }) => {
return acknowledge();
}

const refresh = requestDownloadsRefresh(env, project, deliveryId);
const refresh = requestDownloadsRefresh(env, project, deliveryId).then(() => exports.DownloadsPages.invalidate(project));
if (locals.cfContext) {
locals.cfContext.waitUntil(refresh);
} else {
Expand Down
8 changes: 8 additions & 0 deletions src/utils/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ export function isDownloadProjectId(value: unknown): value is DownloadProjectId
return typeof value === "string" && DOWNLOAD_PROJECT_ID_SET.has(value);
}

export function downloadsPagePath(project: DownloadProjectId): `/downloads/${DownloadProjectId}` {
return `/downloads/${project}`;
}

export function downloadsPageCacheTag(project: DownloadProjectId): `downloads:${DownloadProjectId}` {
return `downloads:${project}`;
}

export function downloadRegionForContinent(continent?: string): DownloadRegion {
if (continent === "EU" || continent === "AF") return "weur";
if (continent === "AS" || continent === "OC") return "apac";
Expand Down
39 changes: 35 additions & 4 deletions src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { handle } from "@astrojs/cloudflare/handler";
import { DOWNLOAD_PROJECT_IDS, isDownloadProjectId } from "./utils/download";
import { WorkerEntrypoint } from "cloudflare:workers";
import {
DOWNLOAD_PROJECT_IDS,
downloadsPageCacheTag,
downloadsPagePath,
isDownloadProjectId,
type DownloadProjectId,
} from "./utils/download";
import { PAPER_PLAYERCOUNT_KEY, fetchPaperBstatsPlayerCount } from "./utils/bstats";
import { DOWNLOADS_LIVE_PATH } from "./utils/downloads-live-path";
import {
Expand All @@ -14,6 +21,26 @@ export { DownloadsUpdateCoordinator, DownloadsWebSocketShard };

const PLAYER_COUNT_CRON = "*/10 * * * *";
const DOWNLOADS_RECONCILIATION_CRON = "0 * * * *";
const DOWNLOADS_PAGE_PATHS: ReadonlySet<string> = new Set(DOWNLOAD_PROJECT_IDS.map(downloadsPagePath));

/**
* The cache-enabled Worker entrypoint for dynamic download pages.
*
* Keep the default entrypoint uncached: it also serves assets, whose otherwise
* free requests become billed when Workers Cache is enabled for that entrypoint.
*/
export class DownloadsPages extends WorkerEntrypoint<Env> {
override fetch(request: Request): Promise<Response> {
return handle(request, this.env, this.ctx);
}

async invalidate(project: DownloadProjectId): Promise<void> {
const cache = this.ctx.cache;
if (!cache) throw new Error("Workers Cache is not enabled for the downloads pages entrypoint");
const result = await cache.purge({ tags: [downloadsPageCacheTag(project)] });
if (!result.success) throw new Error(`Failed to purge ${project} downloads page cache`);
}
}

export default {
async fetch(request, env, ctx) {
Expand All @@ -25,21 +52,25 @@ export default {
url.searchParams.set("region", region);
return downloadShardStub(env, project, region).fetch(new Request(url, request));
}
if (DOWNLOADS_PAGE_PATHS.has(url.pathname)) {
return ctx.exports.DownloadsPages.fetch(request);
}
return handle(request, env, ctx);
},
async scheduled(controller, env, _ctx) {
async scheduled(controller, env, ctx) {
if (controller.cron === PLAYER_COUNT_CRON) {
await updateStatsCache(env);
} else if (controller.cron === DOWNLOADS_RECONCILIATION_CRON) {
await updateDownloadsPageCache(env);
await updateDownloadsPageCache(env, ctx);
}
},
} satisfies ExportedHandler<Env>;

async function updateDownloadsPageCache(env: Env) {
async function updateDownloadsPageCache(env: Env, ctx: ExecutionContext) {
for (const project of DOWNLOAD_PROJECT_IDS) {
try {
await requestDownloadsRefresh(env, project);
await ctx.exports.DownloadsPages.invalidate(project);
} catch (error) {
console.error(
JSON.stringify({
Expand Down
17 changes: 17 additions & 0 deletions wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
"main": "./src/worker.ts",
"compatibility_date": "2026-02-19",
"compatibility_flags": ["nodejs_compat", "disable_nodejs_process_v2"],
"cache": {
"enabled": true,
},
"exports": {
"default": {
"type": "worker",
"cache": {
"enabled": false,
},
},
"DownloadsPages": {
"type": "worker",
"cache": {
"enabled": true,
},
},
},
"assets": {
"binding": "ASSETS",
"directory": "./dist",
Expand Down
Loading