From 310296b55f078b8565f2b1994726886b740e35b6 Mon Sep 17 00:00:00 2001 From: Linus Flood Date: Fri, 21 Mar 2025 09:35:36 +0000 Subject: [PATCH] Merged in feat/warmup-cache-function (pull request #1581) Feat/warmup cache function * WIP * Fix warmup for all languages * Cleanup * Added env flag so we can disable warmup * Changed time to 04.00 UTC since backend updates their data at 03.00 UTC * Add return statements * Merge branch 'master' into feat/warmup-cache-function Approved-by: Anton Gunnarsson --- apps/scandic-web/app/api/hoteldata/route.ts | 41 +++++++++++++++++++ apps/scandic-web/env/server.ts | 8 ++++ .../functions/hoteldata-da-background.mts | 12 ++++++ .../functions/hoteldata-de-background.mts | 12 ++++++ .../functions/hoteldata-en-background.mts | 12 ++++++ .../functions/hoteldata-fi-background.mts | 12 ++++++ .../functions/hoteldata-no-background.mts | 12 ++++++ .../functions/hoteldata-sv-background.mts | 12 ++++++ .../scandic-web/netlify/functions/sitemap.mts | 3 ++ apps/scandic-web/netlify/utils/hoteldata.ts | 30 ++++++++++++++ .../server/routers/hotels/input.ts | 6 +++ .../server/routers/hotels/query.ts | 13 ++++-- 12 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 apps/scandic-web/app/api/hoteldata/route.ts create mode 100644 apps/scandic-web/netlify/functions/hoteldata-da-background.mts create mode 100644 apps/scandic-web/netlify/functions/hoteldata-de-background.mts create mode 100644 apps/scandic-web/netlify/functions/hoteldata-en-background.mts create mode 100644 apps/scandic-web/netlify/functions/hoteldata-fi-background.mts create mode 100644 apps/scandic-web/netlify/functions/hoteldata-no-background.mts create mode 100644 apps/scandic-web/netlify/functions/hoteldata-sv-background.mts create mode 100644 apps/scandic-web/netlify/utils/hoteldata.ts diff --git a/apps/scandic-web/app/api/hoteldata/route.ts b/apps/scandic-web/app/api/hoteldata/route.ts new file mode 100644 index 000000000..b55e13a59 --- /dev/null +++ b/apps/scandic-web/app/api/hoteldata/route.ts @@ -0,0 +1,41 @@ +import { type NextRequest, NextResponse } from "next/server" + +import { env } from "@/env/server" +import { serverClient } from "@/lib/trpc/server" + +import { languageSchema } from "@/utils/languages" + +export const dynamic = "force-dynamic" + +export async function GET(request: NextRequest) { + if (!env.ENABLE_WARMUP_HOTEL) { + console.log("[WARMUP] Warmup hotel data is disabled") + return NextResponse.json( + { message: "Warmup hotel data is disabled" }, + { status: 200 } + ) + } + + try { + const searchParams = request.nextUrl.searchParams + const lang = searchParams.get("lang") + const parsedLang = languageSchema.safeParse(lang) + + if (!parsedLang.success) { + throw new Error("[WARMUP] Invalid language provided") + } + + const hotels = await serverClient().hotel.hotels.getAllHotels.get({ + lang: parsedLang.data, + }) + return NextResponse.json(hotels) + } catch (error) { + console.error("[WARMUP] error", error) + return NextResponse.json( + { + error: "Failed to fetch all hotels", + }, + { status: 500, statusText: "Internal Server Error" } + ) + } +} diff --git a/apps/scandic-web/env/server.ts b/apps/scandic-web/env/server.ts index 77247ee6e..a08847ad2 100644 --- a/apps/scandic-web/env/server.ts +++ b/apps/scandic-web/env/server.ts @@ -192,6 +192,13 @@ export const env = createEnv({ ? z.string() : z.string().optional().default("dev"), GIT_SHA: z.string().optional(), + ENABLE_WARMUP_HOTEL: z + .string() + // only allow "true" or "false" + .refine((s) => s === "true" || s === "false") + // transform to boolean + .transform((s) => s === "true") + .default("true"), }, emptyStringAsUndefined: true, runtimeEnv: { @@ -285,6 +292,7 @@ export const env = createEnv({ REDIS_API_KEY: process.env.REDIS_API_KEY, BRANCH: process.env.BRANCH, GIT_SHA: process.env.GIT_SHA, + ENABLE_WARMUP_HOTEL: process.env.ENABLE_WARMUP_HOTEL, }, }) diff --git a/apps/scandic-web/netlify/functions/hoteldata-da-background.mts b/apps/scandic-web/netlify/functions/hoteldata-da-background.mts new file mode 100644 index 000000000..d1483376b --- /dev/null +++ b/apps/scandic-web/netlify/functions/hoteldata-da-background.mts @@ -0,0 +1,12 @@ +import { Lang } from "@/constants/languages" +import type { Config, Context } from "@netlify/functions" +import { warmupHotelDataOnLang } from "../utils/hoteldata" + +export default async (_request: Request, _context: Context) => { + await warmupHotelDataOnLang(Lang.da) + return new Response("Warmup success", { status: 200 }) +} + +export const config: Config = { + schedule: "0 4 * * *", +} diff --git a/apps/scandic-web/netlify/functions/hoteldata-de-background.mts b/apps/scandic-web/netlify/functions/hoteldata-de-background.mts new file mode 100644 index 000000000..ea10b2e07 --- /dev/null +++ b/apps/scandic-web/netlify/functions/hoteldata-de-background.mts @@ -0,0 +1,12 @@ +import { Lang } from "@/constants/languages" +import type { Config, Context } from "@netlify/functions" +import { warmupHotelDataOnLang } from "../utils/hoteldata" + +export default async (_request: Request, _context: Context) => { + await warmupHotelDataOnLang(Lang.de) + return new Response("Warmup success", { status: 200 }) +} + +export const config: Config = { + schedule: "5 4 * * *", +} diff --git a/apps/scandic-web/netlify/functions/hoteldata-en-background.mts b/apps/scandic-web/netlify/functions/hoteldata-en-background.mts new file mode 100644 index 000000000..bb82dc121 --- /dev/null +++ b/apps/scandic-web/netlify/functions/hoteldata-en-background.mts @@ -0,0 +1,12 @@ +import { Lang } from "@/constants/languages" +import type { Config, Context } from "@netlify/functions" +import { warmupHotelDataOnLang } from "../utils/hoteldata" + +export default async (_request: Request, _context: Context) => { + await warmupHotelDataOnLang(Lang.en) + return new Response("Warmup success", { status: 200 }) +} + +export const config: Config = { + schedule: "10 4 * * *", +} diff --git a/apps/scandic-web/netlify/functions/hoteldata-fi-background.mts b/apps/scandic-web/netlify/functions/hoteldata-fi-background.mts new file mode 100644 index 000000000..8f1d45e8d --- /dev/null +++ b/apps/scandic-web/netlify/functions/hoteldata-fi-background.mts @@ -0,0 +1,12 @@ +import { Lang } from "@/constants/languages" +import type { Config, Context } from "@netlify/functions" +import { warmupHotelDataOnLang } from "../utils/hoteldata" + +export default async (_request: Request, _context: Context) => { + await warmupHotelDataOnLang(Lang.fi) + return new Response("Warmup success", { status: 200 }) +} + +export const config: Config = { + schedule: "15 4 * * *", +} diff --git a/apps/scandic-web/netlify/functions/hoteldata-no-background.mts b/apps/scandic-web/netlify/functions/hoteldata-no-background.mts new file mode 100644 index 000000000..2e2eecd4c --- /dev/null +++ b/apps/scandic-web/netlify/functions/hoteldata-no-background.mts @@ -0,0 +1,12 @@ +import { Lang } from "@/constants/languages" +import type { Config, Context } from "@netlify/functions" +import { warmupHotelDataOnLang } from "../utils/hoteldata" + +export default async (_request: Request, _context: Context) => { + await warmupHotelDataOnLang(Lang.no) + return new Response("Warmup success", { status: 200 }) +} + +export const config: Config = { + schedule: "20 4 * * *", +} diff --git a/apps/scandic-web/netlify/functions/hoteldata-sv-background.mts b/apps/scandic-web/netlify/functions/hoteldata-sv-background.mts new file mode 100644 index 000000000..2aeae74a7 --- /dev/null +++ b/apps/scandic-web/netlify/functions/hoteldata-sv-background.mts @@ -0,0 +1,12 @@ +import { Lang } from "@/constants/languages" +import type { Config, Context } from "@netlify/functions" +import { warmupHotelDataOnLang } from "../utils/hoteldata" + +export default async (_request: Request, _context: Context) => { + await warmupHotelDataOnLang(Lang.sv) + return new Response("Warmup success", { status: 200 }) +} + +export const config: Config = { + schedule: "25 4 * * *", +} diff --git a/apps/scandic-web/netlify/functions/sitemap.mts b/apps/scandic-web/netlify/functions/sitemap.mts index ba0ae2b4a..7c1abe760 100644 --- a/apps/scandic-web/netlify/functions/sitemap.mts +++ b/apps/scandic-web/netlify/functions/sitemap.mts @@ -17,7 +17,10 @@ export default async (request: Request, _context: Context) => { }) } catch (error) { console.error(`Error syncing sitemap: ${error}`) + return new Response("Failed to sync sitemap", { status: 500 }) } + + return new Response("Sitemap synced successfully", { status: 200 }) } export const config: Config = { diff --git a/apps/scandic-web/netlify/utils/hoteldata.ts b/apps/scandic-web/netlify/utils/hoteldata.ts new file mode 100644 index 000000000..95a5c924d --- /dev/null +++ b/apps/scandic-web/netlify/utils/hoteldata.ts @@ -0,0 +1,30 @@ +import type { Lang } from "@/constants/languages" + +export async function warmupHotelDataOnLang(lang: Lang) { + const PUBLIC_URL = Netlify.env.get("PUBLIC_URL") + console.info( + `[WARMUP] Started warmup cache hoteldata for language ${lang} at: ${new Date().toISOString()}!` + ) + + try { + const hotelsResponse = await fetch( + `${PUBLIC_URL}/api/hoteldata?lang=${lang}`, + { + headers: { cache: "no-store" }, + } + ) + + if (!hotelsResponse.ok) { + throw new Error( + `[WARMUP] Failed to warmup cache for hotels on language ${lang} with error: ${hotelsResponse.statusText}` + ) + } + + const hotels = await hotelsResponse.json() + console.info(`[WARMUP] Retrieved ${hotels.length} hotels.`) + } catch (error) { + console.error( + `[WARMUP] Error warming cache with hoteldata on language ${lang} with error: ${error}` + ) + } +} diff --git a/apps/scandic-web/server/routers/hotels/input.ts b/apps/scandic-web/server/routers/hotels/input.ts index fcf43d666..796f69044 100644 --- a/apps/scandic-web/server/routers/hotels/input.ts +++ b/apps/scandic-web/server/routers/hotels/input.ts @@ -92,6 +92,12 @@ export const nearbyHotelIdsInput = z.object({ hotelId: z.string(), }) +export const getAllHotelsInput = z + .object({ + lang: z.nativeEnum(Lang), + }) + .optional() + export const breakfastPackageInputSchema = z.object({ adults: z.number().min(1, { message: "at least one adult is required" }), fromDate: z diff --git a/apps/scandic-web/server/routers/hotels/query.ts b/apps/scandic-web/server/routers/hotels/query.ts index 3e0b124ca..b6a724dc1 100644 --- a/apps/scandic-web/server/routers/hotels/query.ts +++ b/apps/scandic-web/server/routers/hotels/query.ts @@ -26,6 +26,7 @@ import { breakfastPackageInputSchema, cityCoordinatesInputSchema, getAdditionalDataInputSchema, + getAllHotelsInput, getHotelsByCityIdentifierInput, getHotelsByCountryInput, getHotelsByCSFilterInput, @@ -1144,14 +1145,18 @@ export const hotelQueryRouter = router({ }), }), getAllHotels: router({ - get: serviceProcedure.query(async function ({ ctx }) { + get: serviceProcedure.input(getAllHotelsInput).query(async function ({ + input, + ctx, + }) { + const lang = input?.lang ?? ctx.lang const countries = await getCountries({ - lang: ctx.lang, + lang: lang, serviceToken: ctx.serviceToken, }) if (!countries) { - return null + throw new Error("Unable to fetch countries") } const countryNames = countries.data.map((country) => country.name) @@ -1165,7 +1170,7 @@ export const hotelQueryRouter = router({ const hotels = await getHotelsByHotelIds({ hotelIds, - lang: ctx.lang, + lang: lang, serviceToken: ctx.serviceToken, }) return hotels