From 84fd934fe1fdb9571b7c058f176d75cf2b54653b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Tue, 21 Nov 2023 21:19:08 +0100 Subject: [PATCH] Try custom cache (#9) * Try custom cache * Fix redis cache * Comment --- .env.example | 4 ++ bun.lockb | Bin 284396 -> 285113 bytes package.json | 1 + src/lib/api.ts | 106 +++++++++++++++++++++------------------------- src/lib/cache.ts | 72 +++++++++++++++++++++++++++++++ src/middleware.ts | 5 ++- 6 files changed, 129 insertions(+), 59 deletions(-) create mode 100644 src/lib/cache.ts diff --git a/.env.example b/.env.example index 7fc6b0862..18923a3b2 100644 --- a/.env.example +++ b/.env.example @@ -16,3 +16,7 @@ GITBOOK_MODE=multi # Use a different GitBook environment by changing the API URL # GITBOOK_API_URL=https://api.gitbook.com + +# Use upstash for caching +# UPSTASH_REDIS_REST_URL +# UPSTASH_REDIS_REST_TOKEN diff --git a/bun.lockb b/bun.lockb index 0162cf3d0978ab04fc933868107c31a9747e9b85..4c7450de7442056e71a5a557575e61e37348f333 100755 GIT binary patch delta 51806 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 RYS)vtm5Uwg%Eabx{tr{mS_J?A delta 51638 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 H^oRcfv?LkX diff --git a/package.json b/package.json index c6265eaf4..77dc987ab 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@geist-ui/icons": "^1.0.2", "@gitbook/api": "^0.15.0", "@readme/openapi-parser": "^2.5.0", + "@upstash/redis": "^1.25.1", "ajv": "^8.12.0", "assert-never": "^1.2.1", "bun-types": "^1.0.7", diff --git a/src/lib/api.ts b/src/lib/api.ts index 7198a547e..5734343fa 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,9 +1,10 @@ import 'server-only'; import { ContentVisibility, GitBookAPI, JSONDocument } from '@gitbook/api'; -import { unstable_cache } from 'next/cache'; import { headers } from 'next/headers'; +import { cache } from './cache'; + /** * Create an API client for the current request. */ @@ -28,85 +29,74 @@ export function api(): GitBookAPI { /** * Get a space by its ID. */ -export const getSpace = unstable_cache( - async (spaceId: string) => { - const { data } = await api().spaces.getSpaceById(spaceId); - return data; - }, - ['api', 'spaces'], - { - tags: ['api', 'spaces'], - }, -); +export const getSpace = cache('api.getSpace', async (spaceId: string) => { + const { data } = await api().spaces.getSpaceById(spaceId, { + cache: 'no-store', + }); + return data; +}); /** * Get the current revision of a space */ -export const getCurrentRevision = unstable_cache( - async (spaceId: string) => { - const { data } = await api().spaces.getCurrentRevision(spaceId); - return data; - }, - ['api', 'revisions'], - { - tags: ['api', 'revisions'], - }, -); +export const getCurrentRevision = cache('api.getCurrentRevision', async (spaceId: string) => { + const { data } = await api().spaces.getCurrentRevision(spaceId, { + cache: 'no-store', + }); + return data; +}); /** * Get the document for a page. */ -export const getPageDocument = unstable_cache( +export const getPageDocument = cache( + 'api.getPageDocument', async (spaceId: string, revisionId: string, pageId: string) => { - const { data } = await api().spaces.getPageInRevisionById(spaceId, revisionId, pageId); + const { data } = await api().spaces.getPageInRevisionById( + spaceId, + revisionId, + pageId, + {}, + { + cache: 'no-store', + }, + ); // @ts-ignore return data.document as JSONDocument; }, - ['api', 'documents'], - { - tags: ['api', 'documents'], - }, ); /** * Get the customization settings for a space. */ -export const getSpaceCustomization = unstable_cache( - async (spaceId: string) => { - const { data } = await api().spaces.getSpacePublishingCustomizationById(spaceId); - return data; - }, - ['api', 'customization'], - { - tags: ['api', 'customization'], - }, -); +export const getSpaceCustomization = cache('api.getSpaceCustomization', async (spaceId: string) => { + const { data } = await api().spaces.getSpacePublishingCustomizationById(spaceId, { + cache: 'no-store', + }); + return data; +}); /** * Get the infos about a collection by its ID. */ -export const getCollection = unstable_cache( - async (spaceId: string) => { - const { data } = await api().collections.getCollectionById(spaceId); - return data; - }, - ['api', 'collections'], - { - tags: ['api', 'collections'], - }, -); +export const getCollection = cache('api.getCollection', async (spaceId: string) => { + const { data } = await api().collections.getCollectionById(spaceId, { + cache: 'no-store', + }); + return data; +}); /** * List all the spaces variants published in a collection. */ -export const getCollectionSpaces = unstable_cache( - async (spaceId: string) => { - const { data } = await api().collections.listSpacesInCollectionById(spaceId); - // TODO: do this filtering on the API side - return data.items.filter((space) => space.visibility === ContentVisibility.InCollection); - }, - ['api', 'collections', 'spaces'], - { - tags: ['api', 'collections'], - }, -); +export const getCollectionSpaces = cache('api.getCollectionSpaces', async (spaceId: string) => { + const { data } = await api().collections.listSpacesInCollectionById( + spaceId, + {}, + { + cache: 'no-store', + }, + ); + // TODO: do this filtering on the API side + return data.items.filter((space) => space.visibility === ContentVisibility.InCollection); +}); diff --git a/src/lib/cache.ts b/src/lib/cache.ts new file mode 100644 index 000000000..93778ce66 --- /dev/null +++ b/src/lib/cache.ts @@ -0,0 +1,72 @@ +import { Redis } from '@upstash/redis'; + +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 ttl = 60 * 60 * 24; +const memoryCache = new Map(); + +/** + * Cache data from an async function. + * We don't use the next.js cache because it has a 2MB limit. + */ +export function cache( + fnName: string, + fn: (...args: Args) => Promise, +): (...args: Args) => Promise { + return async (...args: Args) => { + const key = getCacheKey(fnName, args); + + const cachedValue = await getCacheValue(key); + if (cachedValue !== null) { + return cachedValue; + } + + const result = await fn(...args); + + await setCacheValue(key, result); + + return result; + }; +} + +/** + * Create a cache key from a function name and its arguments. + */ +function getCacheKey(fnName: string, args: string[]) { + return `${fnName}(${args.join(',')})`; +} + +/** + * Get a value from the cache. + */ +async function getCacheValue(key: string) { + if (memoryCache.has(key)) { + return memoryCache.get(key); + } + + if (redis) { + const value = await redis.get(key); + return value; + } + + return null; +} + +/** + * Set a value in the cache. + */ +async function setCacheValue(key: string, value: any) { + memoryCache.set(key, value); + + if (redis) { + await redis.set(key, value, { + ex: ttl, + }); + } +} diff --git a/src/middleware.ts b/src/middleware.ts index 00de6c713..9d47e865f 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -163,7 +163,10 @@ async function lookupSpaceInMultiPathMode( return { target: 'content', - redirect: new URL(`/` + redirect.hostname + redirect.pathname + redirect.search, url).toString(), + redirect: new URL( + `/` + redirect.hostname + redirect.pathname + redirect.search, + url, + ).toString(), }; }