Files
gitbook/src/lib/cache/http.ts
T
Samy Pessé 55d1e538d9 More resilient caching and use of KV (#222)
* Add unit tests for "race"

* Reduce to 80s

* Implement a Cloudflare KV cache

* Format

* Lint

* Fix tagging of entries in KV

* No longer use HTTP cache tags

* Simplify tags to only keep 2

* Implement a blockFallback logic

* Improve the block fallback logic

* More tests

* Start introducing a always optional signal on all cache ops

* Correctly pass signal end to end

* Fix one more case and add tests

* Fix it

* Add test for error

* Fix error handling

* Simplify even more

* Improve logs

* Improve logs / measurements

* Fix timing

* Fix read cache duration and add minor tests

* Log redis time

* Change replication logic

* Fix redis errors

* Log more

* More logs and test memory first

* Improve tracing for cache backends

* Ignore all dependencies

* Log the key in the cache low level traces
2024-03-08 09:43:30 +01:00

57 lines
1.6 KiB
TypeScript

import parseCacheControl from 'parse-cache-control';
import { CacheResult } from './cache';
/**
* Options to pass to the `fetch` call to disable the Next data-cache when wrapped in `cache()`.
*/
export const noCacheFetchOptions: Partial<RequestInit> = {
// Cloudflare doesn't support the `cache` directive before next-on-pages patches the fetch function
// https://github.com/cloudflare/workerd/issues/698
next: {
revalidate: 0,
},
};
/**
* Parse an HTTP response into a cache entry.
*/
export function parseCacheResponse(response: Response): {
ttl: number;
tags: string[];
} {
const ageHeader = response.headers.get('age');
const age = ageHeader ? parseInt(ageHeader, 10) : 0;
const cacheControlHeader = response.headers.get('cache-control');
const cacheControl = cacheControlHeader ? parseCacheControl(cacheControlHeader) : null;
const entry = {
ttl: 60 * 60 * 24,
tags: [],
};
if (cacheControl && cacheControl['max-age']) {
entry.ttl = Math.max(0, cacheControl['max-age'] - age - 60);
}
return entry;
}
/**
* Cache an HTTP response.
*/
export function cacheResponse<Result, DefaultData = Result>(
response: Response & { data: Result },
defaultEntry: Partial<CacheResult<DefaultData>> = {},
): CacheResult<DefaultData extends Result ? Result : DefaultData> {
const parsed = parseCacheResponse(response);
return {
ttl: defaultEntry.ttl ?? parsed.ttl,
tags: [...(defaultEntry.tags ?? []), ...parsed.tags],
// @ts-ignore
data: defaultEntry.data ?? response.data,
};
}