Compare commits

...

1 Commits

Author SHA1 Message Date
Olav Sundfør aab292c353 Workaround for broken cache expiry handling
Deno's cache API does not respect expiry dates.
This meant that feeds were cached much longer than intended.

This PR implments a manual cache handling instead of relying on
Deno's implementation. Relevant issue: https://github.com/denoland/deno/issues/25795
2025-10-01 09:49:11 +02:00
2 changed files with 22 additions and 2 deletions

View File

@ -27,6 +27,7 @@ export function responseXML(body: string, status: Status) {
export const withExpiry = <T>(response: Response, ttlInSeconds: number) => {
const clonedResponse = response.clone();
clonedResponse.headers.set("Cache-Control", `max-age=${ttlInSeconds}`);
clonedResponse.headers.set("Expires", new Date(Date.now() + ttlInSeconds * 1000).toUTCString());
return clonedResponse;
};

View File

@ -5,6 +5,23 @@ import { responseJSON, responseXML, withExpiry } from "../../../lib/utils.ts";
const FEED_CACHE_KEY = "feeds-cache";
// Deno's cache API does not respect these headers.
// Until it does, manual expiry handling is needed.
// When it's working, this function would not be needed.
// See: https://github.com/denoland/deno/issues/25795
function isExpired(headers: Headers) {
const expiresHeader = headers.get("Expires");
if (!expiresHeader) {
console.log("No Expires header found, treating as expired");
return true;
}
const now = new Date();
const expiryDate = new Date(expiresHeader);
const expired = now > expiryDate;
return expired;
}
export const handler = async (
request: Request,
ctx: FreshContext,
@ -13,11 +30,13 @@ export const handler = async (
const cache = await caches.open(FEED_CACHE_KEY);
const cachedResponse = await cache.match(request);
if (cachedResponse) {
if (cachedResponse && !isExpired(cachedResponse.headers)) {
console.log(`Cache hit for feed ${seriesId}`);
return cachedResponse;
}
console.log(`Fetching feed for ${seriesId}`);
const series = await caching.getSeries({ id: seriesId });
if (!series) {
return responseJSON({ message: "Series not found" }, STATUS_CODE.NotFound);
@ -28,7 +47,7 @@ export const handler = async (
const response = withExpiry(
responseXML(feed, STATUS_CODE.OK),
// 2 hours
60 * 60 * 2,
2 * 60 * 60,
);
await cache.put(request, response.clone());