From 215c724a9bae85ff970fa6489b79199183b32e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Fri, 22 Dec 2023 11:05:14 +0100 Subject: [PATCH] Use Cloudflare Cache API as one of the cache backend (#59) * Implement cache for cloudflare * Start using it * Fix cache use * Generate proper URLs * Comment * Fix cache always resulting in cache miss * Log * Correctly cancel redis * Write to fallback caches * Disable memory cache * Re-enable memory cache * Try patching * Use it * Also patch package.json * Fix TS errors * Remove yarn.lock * Fix local error * Lint * Try bunx to fix vercel build * Update lockfile * Add back revalidating --- bun.lockb | Bin 440935 -> 447307 bytes package.json | 5 +- patches/@cloudflare+next-on-pages+1.8.2.patch | 89 ++++++++++ src/app/.gitbook/revalidate/route.ts | 7 +- src/lib/analytics.ts | 2 +- src/lib/cache/backends.ts | 10 ++ src/lib/cache/cache.ts | 70 +++++--- src/lib/cache/cloudflare.ts | 77 ++++++++ src/lib/cache/memory.ts | 2 + src/lib/cache/redis.ts | 165 ++++++++++-------- src/lib/cache/revalidateTags.ts | 22 ++- src/lib/cache/types.ts | 9 +- src/lib/cache/waitUntil.ts | 14 ++ 13 files changed, 361 insertions(+), 111 deletions(-) create mode 100644 patches/@cloudflare+next-on-pages+1.8.2.patch create mode 100644 src/lib/cache/backends.ts create mode 100644 src/lib/cache/cloudflare.ts create mode 100644 src/lib/cache/waitUntil.ts diff --git a/bun.lockb b/bun.lockb index 819122a899f7bd74d896d1a02497e5b7f4971927..eabb20609a7e87b273a82b22e2af4b81d7c118ec 100755 GIT binary patch delta 81065 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 ++/** ++ * returns the request's execution context (usually referred as ctx). ++ * ++ * Note: ++ * This function throws when run on the client, where there is execution context. ++ * This function returns the mocked execution context in non pages environments. ++ * ++ * @returns the request's execution context ++ */ ++export declare const getRequestCloudflareContext: () => { ctx: ExecutionContext, cf: IncomingRequestCfProperties }; +diff --git a/node_modules/@cloudflare/next-on-pages/dist/helpers/index.d.ts b/node_modules/@cloudflare/next-on-pages/dist/helpers/index.d.ts +new file mode 100644 +index 0000000..4a415d2 +--- /dev/null ++++ b/node_modules/@cloudflare/next-on-pages/dist/helpers/index.d.ts +@@ -0,0 +1 @@ ++export * from './getRequestCloudflareContext'; +diff --git a/node_modules/@cloudflare/next-on-pages/dist/helpers/index.js b/node_modules/@cloudflare/next-on-pages/dist/helpers/index.js +new file mode 100644 +index 0000000..c6e2065 +--- /dev/null ++++ b/node_modules/@cloudflare/next-on-pages/dist/helpers/index.js +@@ -0,0 +1,15 @@ ++// src/helpers/getRequestExecutionContext.ts ++var getRequestCloudflareContext = () => { ++ if (typeof process === "undefined") { ++ throw new Error( ++ "Error: trying to access the request execution context on the client" ++ ); ++ } ++ const cloudflare = process.env.cloudflare; ++ if (cloudflare) ++ return cloudflare; ++ return null; ++ }; ++ export { ++ getRequestCloudflareContext ++ }; +\ No newline at end of file +diff --git a/node_modules/@cloudflare/next-on-pages/package.json b/node_modules/@cloudflare/next-on-pages/package.json +index 494e9a9..f0e1e21 100644 +--- a/node_modules/@cloudflare/next-on-pages/package.json ++++ b/node_modules/@cloudflare/next-on-pages/package.json +@@ -3,12 +3,16 @@ + "version": "1.8.2", + "bin": "./bin/index.js", + "exports": { +- "./__experimental__next-dev": "./dist/next-dev/index.cjs" ++ "./__experimental__next-dev": "./dist/next-dev/index.cjs", ++ "./helpers": "./dist/helpers/index.js" + }, + "typesVersions": { + "*": { + "__experimental__next-dev": [ + "./dist/next-dev/index.d.ts" ++ ], ++ "helpers": [ ++ "./dist/helpers/index.d.ts" + ] + } + }, +diff --git a/node_modules/@cloudflare/next-on-pages/templates/_worker.js/index.ts b/node_modules/@cloudflare/next-on-pages/templates/_worker.js/index.ts +index 929f6cc..7164930 100644 +--- a/node_modules/@cloudflare/next-on-pages/templates/_worker.js/index.ts ++++ b/node_modules/@cloudflare/next-on-pages/templates/_worker.js/index.ts +@@ -33,9 +33,15 @@ export default { + return new Response(responseBody, { status: 503 }); + } + ++ const cloudflare = { ++ cf: request.cf, ++ env, ++ ctx, ++ }; ++ + return envAsyncLocalStorage.run( + // NOTE: The `SUSPENSE_CACHE_URL` is used to tell the Next.js Fetch Cache where to send requests. +- { ...env, NODE_ENV: __NODE_ENV__, SUSPENSE_CACHE_URL }, ++ { ...env, cloudflare, NODE_ENV: __NODE_ENV__, SUSPENSE_CACHE_URL }, + async () => { + const url = new URL(request.url); + if (url.pathname.startsWith('/_next/image')) { diff --git a/src/app/.gitbook/revalidate/route.ts b/src/app/.gitbook/revalidate/route.ts index 05da126d1..049cac473 100644 --- a/src/app/.gitbook/revalidate/route.ts +++ b/src/app/.gitbook/revalidate/route.ts @@ -3,12 +3,17 @@ import { revalidateTags } from '@/lib/cache'; export const runtime = 'edge'; +interface JsonBody { + tags: string[]; + purge?: boolean; +} + /** * Revalidate cached data based on tags. * The body should be a JSON with { tags: string[] } */ export async function POST(req: NextRequest) { - const json = await req.json(); + const json = (await req.json()) as JsonBody; if (!json.tags || !Array.isArray(json.tags)) { return NextResponse.json( diff --git a/src/lib/analytics.ts b/src/lib/analytics.ts index 22ee78ed9..fcf4898fc 100644 --- a/src/lib/analytics.ts +++ b/src/lib/analytics.ts @@ -56,7 +56,7 @@ async function fetchVisitorID(): Promise { mode: 'cors', // Need to use cors as we are on a different domain. }); - const { deviceId } = await resp.json(); + const { deviceId } = (await resp.json()) as { deviceId: string }; return deviceId; } catch (error) { return proposed; diff --git a/src/lib/cache/backends.ts b/src/lib/cache/backends.ts new file mode 100644 index 000000000..e4e005df0 --- /dev/null +++ b/src/lib/cache/backends.ts @@ -0,0 +1,10 @@ +import { cloudflareCache } from './cloudflare'; +import { memoryCache } from './memory'; +import { redisCache } from './redis'; + +export const cacheBackends = [ + memoryCache, + redisCache, + // Cloudflare should be last to delete its cache from the listing of redis/memory + cloudflareCache, +]; diff --git a/src/lib/cache/cache.ts b/src/lib/cache/cache.ts index 2965b013f..36b2ba7e0 100644 --- a/src/lib/cache/cache.ts +++ b/src/lib/cache/cache.ts @@ -1,8 +1,8 @@ import hash from 'object-hash'; -import { memoryCache } from './memory'; -import { redisCache } from './redis'; +import { cacheBackends } from './backends'; import { CacheEntry } from './types'; +import { waitUntil } from './waitUntil'; export type CacheFunction = ((...args: Args) => Promise) & { /** @@ -62,10 +62,8 @@ export function cache( }; // Write it to the cache - // As soon as it'll be possible with next-on-pages, we should `waitUntil` - // to delay writing the cache after the response has been sent to the client. if (result.ttl && result.ttl > 0) { - await setCacheEntry(key, cacheEntry); + await waitUntil(setCacheEntry(key, cacheEntry)); } const writeCacheDuration = now() - startTime - fetchDuration; @@ -79,18 +77,15 @@ export function cache( const fetchValue = async (key: string, ...args: Args) => { // Read the cache const startTime = now(); - const hasMemoryHit = !!(await memoryCache.get(key)); const cachedEntry = await getCacheEntry(key); const readCacheDuration = now() - startTime; // Returns it if it exists if (cachedEntry !== null) { console.log( - `cache: ${key} hit in ${readCacheDuration.toFixed( - 0, - )}ms (memory: ${hasMemoryHit}, redis: ${!!redisCache})`, + `cache: ${key} hit on ${cachedEntry[1]} in ${readCacheDuration.toFixed(0)}ms`, ); - return cachedEntry.data; + return cachedEntry[0].data; } const fetched = await revalidate(key, ...args); @@ -99,7 +94,7 @@ export function cache( 0, )}ms, read in ${readCacheDuration.toFixed( 0, - )}ms, write in ${fetched.writeCacheDuration.toFixed(0)}ms (redis: ${!!redisCache})`, + )}ms, write in ${fetched.writeCacheDuration.toFixed(0)}ms`, ); return fetched.data; @@ -153,7 +148,10 @@ export function getCache(name: string): CacheFunction | null { return registeredCaches.get(name) ?? null; } -function getCacheKey(fnName: string, args: any[]) { +/** + * Get a cache key for a function and its arguments. + */ +export function getCacheKey(fnName: string, args: any[]) { let innerKey = args.map((arg) => JSON.stringify(arg)).join(','); // Avoid crazy long keys, by fallbacking to a hash @@ -165,26 +163,42 @@ function getCacheKey(fnName: string, args: any[]) { } async function setCacheEntry(key: string, entry: CacheEntry) { - await Promise.all([memoryCache.set(key, entry), redisCache?.set(key, entry)]); + await Promise.all(cacheBackends.map((backend) => backend.set(key, entry))); } -async function getCacheEntry(key: string): Promise { - const memoryEntry = await memoryCache.get(key); - if (memoryEntry) { - return memoryEntry; +async function getCacheEntry(key: string): Promise<[CacheEntry, string] | null> { + const abort = new AbortController(); + + let result: [CacheEntry, string] | null = null; + + await Promise.all( + cacheBackends.map(async (backend) => { + try { + const entry = await backend.get(key, { signal: abort.signal }); + if (entry && !result) { + result = [entry, backend.name]; + abort.abort(); + } + } catch (error) { + // Ignore all errors + } + }), + ); + + // Write to the fallback caches + if (result) { + const [savedEntry, backendName] = result as [CacheEntry, string]; + + await waitUntil( + Promise.all( + cacheBackends + .filter((backend) => backend.name !== backendName && backend.fallback) + .map((backend) => backend.set(key, savedEntry)), + ), + ); } - try { - const redisEntry = (await redisCache?.get(key)) ?? null; - if (redisEntry) { - await memoryCache.set(key, redisEntry); - } - - return redisEntry; - } catch (error) { - console.error(`Error while getting cache entry for ${key} from redis`, error); - return null; - } + return result; } function now(): number { diff --git a/src/lib/cache/cloudflare.ts b/src/lib/cache/cloudflare.ts new file mode 100644 index 000000000..0f72c3edf --- /dev/null +++ b/src/lib/cache/cloudflare.ts @@ -0,0 +1,77 @@ +import { Buffer } from 'node:buffer'; + +import type { CacheStorage, Cache, Response as WorkerResponse } from '@cloudflare/workers-types'; + +import { CacheBackend, CacheEntry } from './types'; + +/** + * Cache implementation using the Cloudflare Cache API. + * https://developers.cloudflare.com/workers/runtime-apis/cache/ + */ +export const cloudflareCache: CacheBackend = { + name: 'cloudflare', + fallback: true, + async get(key, options) { + const cache = getCache(); + if (!cache) { + return null; + } + + const cacheKey = await serializeKey(key); + const response = await cache.match(cacheKey); + if (!response || options?.signal?.aborted) { + return null; + } + + const entry = await deserializeEntry(response); + return entry; + }, + async set(key, entry) { + const cache = getCache(); + if (cache) { + const cacheKey = await serializeKey(key); + await cache.put(cacheKey, serializeEntry(entry)); + } + }, + async revalidateTags(tags) { + return []; + }, +}; + +function getCache(): Cache | null { + if (typeof caches === 'undefined') { + return null; + } + + // @ts-ignore + return (caches as CacheStorage).default ?? null; +} + +async function serializeKey(key: string): Promise { + const digest = await crypto.subtle.digest( + { + name: 'SHA-256', + }, + new TextEncoder().encode(key), + ); + + const hash = Buffer.from(digest).toString('base64'); + + return `gitbook://gitbook.com/${hash}`; +} + +function serializeEntry(entry: CacheEntry): WorkerResponse { + const headers = new Headers(); + headers.set('Content-Type', 'application/json'); + headers.set('Cache-Control', `public, max-age=${(entry.meta.expiresAt - Date.now()) / 1000}`); + + // @ts-ignore + return new Response(JSON.stringify(entry), { + headers, + }); +} + +async function deserializeEntry(response: WorkerResponse): Promise { + const entry = (await response.json()) as CacheEntry; + return entry; +} diff --git a/src/lib/cache/memory.ts b/src/lib/cache/memory.ts index 5bde5af8b..1ae482337 100644 --- a/src/lib/cache/memory.ts +++ b/src/lib/cache/memory.ts @@ -1,6 +1,8 @@ import { CacheBackend, CacheEntry } from './types'; export const memoryCache: CacheBackend = { + name: 'memory', + fallback: true, async get(key) { const memoryCache = getMemoryCache(); const memoryEntry = memoryCache.get(key); diff --git a/src/lib/cache/redis.ts b/src/lib/cache/redis.ts index 24ba11b28..ff9117981 100644 --- a/src/lib/cache/redis.ts +++ b/src/lib/cache/redis.ts @@ -3,98 +3,115 @@ import { Redis } from '@upstash/redis/cloudflare'; import { CacheBackend, CacheEntry, CacheEntryMeta } from './types'; import { filterOutNullable } from '../typescript'; -const redis = - process.env.UPSTASH_REDIS_REST_URL && process.env.UPSTASH_REDIS_REST_TOKEN - ? new Redis({ - url: process.env.UPSTASH_REDIS_REST_URL, - token: process.env.UPSTASH_REDIS_REST_TOKEN, - }) - : null; - const cacheNamespace = process.env.UPSTASH_REDIS_NAMESPACE ?? 'gitbook'; const cacheVersion = 1; -export const redisCache: CacheBackend | null = redis - ? { - async get(key) { - try { - const [, redisEntry] = await redis - .multi() - .json.numincrby(getRedisKey(key), '$.meta.hits', 1) - .json.get(getRedisKey(key)) - .exec<[any, CacheEntry | null]>(); - if (!redisEntry) { - return null; - } +export const redisCache: CacheBackend = { + name: 'redis', + async get(key, options) { + const redis = getRedis(options?.signal); + if (!redis) { + return null; + } - return redisEntry; - } catch (error) { - // "JSON.NUMINCRBY" throws an error if the key does not exist - if ((error as Error).message.includes('ERR no such key')) { - return null; - } + try { + const [, redisEntry] = await redis + .multi() + .json.numincrby(getRedisKey(key), '$.meta.hits', 1) + .json.get(getRedisKey(key)) + .exec<[any, CacheEntry | null]>(); + if (!redisEntry) { + return null; + } - throw error; - } - }, + return redisEntry; + } catch (error) { + // "JSON.NUMINCRBY" throws an error if the key does not exist + if ((error as Error).message.includes('ERR no such key')) { + return null; + } - async set(key, entry) { - const multi = redis.multi(); + throw error; + } + }, - const redisKey = getRedisKey(key); - const expire = Math.max(0, (entry.meta.expiresAt - Date.now()) / 1000); + async set(key, entry) { + const redis = getRedis(); + if (!redis) { + return; + } - entry.meta.tags.forEach((tag) => { - const redisTagKey = getCacheTagKey(tag); + const multi = redis.multi(); - multi.sadd(redisTagKey, redisKey); + const redisKey = getRedisKey(key); + const expire = Math.max(0, (entry.meta.expiresAt - Date.now()) / 1000); - // Set am expiration on the tag to be the maximum of the expiration of all keys - multi.expire(redisTagKey, expire, 'GT'); - multi.expire(redisTagKey, expire, 'NX'); - }); + entry.meta.tags.forEach((tag) => { + const redisTagKey = getCacheTagKey(tag); - // @ts-ignore - multi.json.set(redisKey, '$', entry); - multi.expire(redisKey, expire); + multi.sadd(redisTagKey, redisKey); - await multi.exec(); - }, + // Set am expiration on the tag to be the maximum of the expiration of all keys + multi.expire(redisTagKey, expire, 'GT'); + multi.expire(redisTagKey, expire, 'NX'); + }); - async revalidateTags(tags) { - const keys = new Set( - ( - await Promise.all(tags.map((tag) => redis.smembers(getCacheTagKey(tag)))) - ).flat(), - ); + // @ts-ignore + multi.json.set(redisKey, '$', entry); + multi.expire(redisKey, expire); - const pipeline = redis.pipeline(); - let metas: Array = []; + await multi.exec(); + }, - if (keys.size > 0) { - metas = ( - await redis.json.mget( - // Hard limit to avoid fetching a massive list of data - Array.from(keys).slice(0, 1000), - '$.meta', - ) - ).flat() as Array; + async revalidateTags(tags) { + const redis = getRedis(); + if (!redis) { + return []; + } - // Finally, delete all keys - keys.forEach((key) => { - pipeline.del(key); - }); - } + const keys = new Set( + (await Promise.all(tags.map((tag) => redis.smembers(getCacheTagKey(tag))))).flat(), + ); - tags.forEach((tag) => { - pipeline.del(getCacheTagKey(tag)); - }); + const pipeline = redis.pipeline(); + let metas: Array = []; - await pipeline.exec(); - return metas.filter(filterOutNullable); - }, - } - : null; + if (keys.size > 0) { + metas = ( + await redis.json.mget( + // Hard limit to avoid fetching a massive list of data + Array.from(keys).slice(0, 1000), + '$.meta', + ) + ).flat() as Array; + + // Finally, delete all keys + keys.forEach((key) => { + pipeline.del(key); + }); + } + + tags.forEach((tag) => { + pipeline.del(getCacheTagKey(tag)); + }); + + await pipeline.exec(); + return metas.filter(filterOutNullable); + }, +}; + +/** + * Get the redis client. + */ +export function getRedis(signal?: AbortSignal) { + return process.env.UPSTASH_REDIS_REST_URL && process.env.UPSTASH_REDIS_REST_TOKEN + ? new Redis({ + url: process.env.UPSTASH_REDIS_REST_URL, + token: process.env.UPSTASH_REDIS_REST_TOKEN, + signal, + }) + : null; +} /** * Get the key for a tag. diff --git a/src/lib/cache/revalidateTags.ts b/src/lib/cache/revalidateTags.ts index a92d5c24d..f4e138a65 100644 --- a/src/lib/cache/revalidateTags.ts +++ b/src/lib/cache/revalidateTags.ts @@ -1,8 +1,8 @@ import pMap from 'p-map'; -import { getCache } from './cache'; -import { memoryCache } from './memory'; -import { redisCache } from './redis'; +import { cacheBackends } from './backends'; +import { getCache, getCacheKey } from './cache'; +import { CacheEntryMeta } from './types'; /** * Revalidate all values associated with tags. @@ -13,9 +13,21 @@ export async function revalidateTags(tags: string[], purge: boolean): Promise(); + const metas: CacheEntryMeta[] = []; - const metas = await redisCache?.revalidateTags(tags); + await Promise.all( + cacheBackends.map(async (backend) => { + const addedMetas = await backend.revalidateTags(tags); + addedMetas.forEach((meta) => { + const key = getCacheKey(meta.cache, meta.args); + if (!processed.has(key)) { + metas.push(meta); + processed.add(key); + } + }); + }), + ); // Refresh the values in the cache if (metas && !purge) { diff --git a/src/lib/cache/types.ts b/src/lib/cache/types.ts index 414d8a80b..e38c79b5d 100644 --- a/src/lib/cache/types.ts +++ b/src/lib/cache/types.ts @@ -31,10 +31,17 @@ export interface CacheEntry { } export interface CacheBackend { + name: string; + + /** + * If true, we'll set entries in this cache that have been found in another cache. + */ + fallback?: boolean; + /** * Get a value from the cache. */ - get(key: string): Promise; + get(key: string, options?: { signal?: AbortSignal }): Promise; /** * Set a value in the cache. diff --git a/src/lib/cache/waitUntil.ts b/src/lib/cache/waitUntil.ts new file mode 100644 index 000000000..8ec6ba4f0 --- /dev/null +++ b/src/lib/cache/waitUntil.ts @@ -0,0 +1,14 @@ +import { getRequestCloudflareContext } from '@cloudflare/next-on-pages/helpers'; + +/** + * Extend the lifetime of the event handler until the promise is resolved. + * https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/#contextwaituntil + */ +export async function waitUntil(promise: Promise) { + const cloudflare = getRequestCloudflareContext(); + if (cloudflare) { + cloudflare.ctx.waitUntil(promise); + } else { + await promise; + } +}