Merged in feat/cms-cache (pull request #682)

Feat/cms cache

Approved-by: Michael Zetterberg
This commit is contained in:
Linus Flood
2024-10-14 10:08:17 +00:00
committed by Michael Zetterberg
5 changed files with 64 additions and 15 deletions

View File

@@ -2,10 +2,6 @@ import { NextResponse } from "next/server"
import { bookingFlow } from "@/constants/routes/hotelReservation"
import { resolve as resolveEntry } from "@/utils/entry"
import { findLang } from "@/utils/languages"
import { removeTrailingSlash } from "@/utils/url"
import { getDefaultRequestHeaders } from "./utils"
import type { NextMiddleware } from "next/server"
@@ -13,8 +9,6 @@ import type { NextMiddleware } from "next/server"
import type { MiddlewareMatcher } from "@/types/middleware"
export const middleware: NextMiddleware = async (request) => {
const { nextUrl } = request
const headers = getDefaultRequestHeaders(request)
return NextResponse.next({
request: {

View File

@@ -6,7 +6,7 @@ import { resolve as resolveEntry } from "@/utils/entry"
import { findLang } from "@/utils/languages"
import { removeTrailingSlash } from "@/utils/url"
import { getDefaultRequestHeaders } from "./utils"
import { fetchAndCacheEntry, getDefaultRequestHeaders } from "./utils"
import type { NextMiddleware } from "next/server"
@@ -21,7 +21,10 @@ export const middleware: NextMiddleware = async (request) => {
const pathNameWithoutLang = pathWithoutTrailingSlash.replace(`/${lang}`, "")
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
const { contentType, uid } = await resolveEntry(pathNameWithoutLang, lang)
const { contentType, uid } = await fetchAndCacheEntry(
pathNameWithoutLang,
lang
)
if (!contentType || !uid) {
throw notFound(

View File

@@ -9,10 +9,9 @@ import {
import { env } from "@/env/server"
import { internalServerError, notFound } from "@/server/errors/next"
import { resolve as resolveEntry } from "@/utils/entry"
import { findLang } from "@/utils/languages"
import { getDefaultRequestHeaders } from "./utils"
import { fetchAndCacheEntry, getDefaultRequestHeaders } from "./utils"
import type { NextMiddleware } from "next/server"
@@ -40,8 +39,11 @@ export const middleware: NextMiddleware = async (request) => {
}
const pathNameWithoutLang = nextUrl.pathname.replace(`/${lang}`, "")
const { uid, contentType } = await resolveEntry(pathNameWithoutLang, lang)
if (!uid) {
const { uid, contentType } = await fetchAndCacheEntry(
pathNameWithoutLang,
lang
)
if (!uid || !contentType) {
throw notFound(
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`
)

View File

@@ -1,5 +1,9 @@
import { stringify } from "querystring"
import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import { resolve as resolveEntry } from "@/utils/entry"
import { findLang } from "@/utils/languages"
import { removeTrailingSlash } from "@/utils/url"
@@ -31,3 +35,49 @@ export function getDefaultRequestHeaders(request: NextRequest) {
return headers
}
const entryResponseCache: Map<
string,
{
contentType: string | null
uid: string | null
expiresAt: number
}
> = new Map()
let size: number = 0
export const fetchAndCacheEntry = async (path: string, lang: Lang) => {
const cacheKey = `${path + lang}`
const cachedResponse = entryResponseCache.get(cacheKey)
if (cachedResponse && cachedResponse.expiresAt > Date.now() / 1000) {
console.log("[CMS MIDDLEWARE]: CACHE HIT")
return cachedResponse
}
if (cachedResponse && cachedResponse.expiresAt < Date.now() / 1000) {
console.log("[CMS MIDDLEWARE]: CACHE STALE")
size -= JSON.stringify(cachedResponse).length
entryResponseCache.delete(cacheKey)
} else {
console.log("[CMS MIDDLEWARE]: CACHE MISS")
}
const { contentType, uid } = await resolveEntry(path, lang)
let expiresAt = Date.now() / 1000
if (!contentType || !uid) {
expiresAt += 600
} else {
expiresAt += 3600 * 12
}
const entryCache = { contentType, uid, expiresAt }
size += JSON.stringify(entryCache).length
console.log("[CMS MIDDLEWARE] Adding to cache", entryCache)
console.log("[CMS MIDDLEWARE] Cache size (total)", size)
entryResponseCache.set(cacheKey, entryCache)
return {
contentType,
uid,
}
}

View File

@@ -13,13 +13,13 @@ import { decryptData } from "@/utils/aes"
import { resolve as resolveEntry } from "@/utils/entry"
import { findLang } from "@/utils/languages"
import { getDefaultRequestHeaders } from "./utils"
import { fetchAndCacheEntry, getDefaultRequestHeaders } from "./utils"
import type { MiddlewareMatcher } from "@/types/middleware"
export const middleware: NextMiddleware = async (request) => {
const { nextUrl } = request
const lang = findLang(nextUrl.pathname)
const lang = findLang(nextUrl.pathname)!
const loginTypeHeader = request.headers.get("loginType")
const loginTypeSearchParam = nextUrl.searchParams.get("loginType")
@@ -64,7 +64,7 @@ export const middleware: NextMiddleware = async (request) => {
const pathNameWithoutLang = nextUrl.pathname.replace(`/${lang}/webview`, "")
const { uid } = await resolveEntry(pathNameWithoutLang, lang)
const { uid } = await fetchAndCacheEntry(pathNameWithoutLang, lang)
if (!uid) {
throw notFound(
`Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}`