From e57e725639eedfd5e5adfa14598121af440dd3d6 Mon Sep 17 00:00:00 2001 From: Liam Date: Sat, 26 Oct 2024 15:16:50 +0100 Subject: [PATCH] optimize requests to scoresaber's api --- .../src/app/(pages)/player/[...slug]/page.tsx | 25 +++++++------------ .../app/(pages)/ranking/[[...slug]]/page.tsx | 17 +++---------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/projects/website/src/app/(pages)/player/[...slug]/page.tsx b/projects/website/src/app/(pages)/player/[...slug]/page.tsx index 24b67a4..16af7b4 100644 --- a/projects/website/src/app/(pages)/player/[...slug]/page.tsx +++ b/projects/website/src/app/(pages)/player/[...slug]/page.tsx @@ -12,8 +12,8 @@ import { ScoreSaberScore } from "@ssr/common/model/score/impl/scoresaber-score"; import ScoreSaberLeaderboard from "@ssr/common/model/leaderboard/impl/scoresaber-leaderboard"; import { fetchPlayerScores } from "@ssr/common/utils/score-utils"; import PlayerScoresResponse from "@ssr/common/response/player-scores-response"; -import { SSRCache } from "@ssr/common/cache"; import { getScoreSaberPlayerFromToken } from "@ssr/common/token-creators"; +import { cache } from "react"; const UNKNOWN_PLAYER = { title: "ScoreSaber Reloaded - Unknown Player", @@ -37,8 +37,9 @@ type PlayerData = { search: string; }; -const playerCache = new SSRCache({ - ttl: 1000 * 60, // 1 minute +const getPlayer = cache(async (id: string): Promise => { + const playerToken = await scoresaberService.lookupPlayer(id); + return playerToken && (await getScoreSaberPlayerFromToken(playerToken, await getCookieValue("playerId"))); }); /** @@ -48,35 +49,27 @@ const playerCache = new SSRCache({ * @param fetchScores whether to fetch the scores * @returns the player data and scores */ -const getPlayerData = async ({ params }: Props, fetchScores: boolean = true): Promise => { +const getPlayerData = cache(async ({ params }: Props, fetchScores: boolean = true): Promise => { const { slug } = await params; const id = slug[0]; // The players id const sort: ScoreSort = (slug[1] as ScoreSort) || (await getCookieValue("lastScoreSort", "recent")); // The sorting method const page = parseInt(slug[2]) || 1; // The page number const search = (slug[3] as string) || ""; // The search query - const cacheId = `${id}-${sort}-${page}-${search}-${fetchScores}`; - if (playerCache.has(cacheId)) { - return playerCache.get(cacheId) as PlayerData; - } - - const playerToken = await scoresaberService.lookupPlayer(id); - const player = playerToken && (await getScoreSaberPlayerFromToken(playerToken, await getCookieValue("playerId"))); + const player = await getPlayer(id); let scores: PlayerScoresResponse | undefined; - if (fetchScores) { + if (fetchScores && player !== undefined) { scores = await fetchPlayerScores("scoresaber", id, page, sort, search); } - const playerData = { + return { sort: sort, page: page, search: search, player: player, scores: scores, }; - playerCache.set(cacheId, playerData); - return playerData; -}; +}); export async function generateMetadata(props: Props): Promise { const { player } = await getPlayerData(props, false); diff --git a/projects/website/src/app/(pages)/ranking/[[...slug]]/page.tsx b/projects/website/src/app/(pages)/ranking/[[...slug]]/page.tsx index 0c3ce64..9cc6e03 100644 --- a/projects/website/src/app/(pages)/ranking/[[...slug]]/page.tsx +++ b/projects/website/src/app/(pages)/ranking/[[...slug]]/page.tsx @@ -1,11 +1,11 @@ import { Metadata } from "next"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; -import NodeCache from "node-cache"; import { ScoreSaberPlayersPageToken } from "@ssr/common/types/token/scoresaber/score-saber-players-page-token"; import Card from "@/components/card"; import RankingData from "@/components/ranking/ranking-data"; import CountryFlag from "@/components/country-flag"; import { normalizedRegionName } from "@ssr/common/utils/region-utils"; +import { cache } from "react"; const UNKNOWN_PAGE = { title: "ScoreSaber Reloaded - Unknown Page", @@ -24,36 +24,27 @@ type RankingPageData = { country: string | undefined; }; -const rankingCache = new NodeCache({ stdTTL: 60, checkperiod: 120 }); - /** * Gets the ranking data. * * @param params the params * @returns the ranking data */ -const getRankingData = async ({ params }: Props): Promise => { +const getRankingData = cache(async ({ params }: Props): Promise => { const { slug } = await params; const country = (slug && slug.length > 1 && (slug[0] as string).toUpperCase()) || undefined; // The country query const page = (slug && parseInt(slug[country != undefined ? 1 : 0])) || 1; // The page number - const cacheId = `${country === undefined ? "global" : country}-${page}`; - if (rankingCache.has(cacheId)) { - return rankingCache.get(cacheId) as RankingPageData; - } - const players = country == undefined ? await scoresaberService.lookupPlayers(page) : await scoresaberService.lookupPlayersByCountry(page, country); - const rankingData = { + return { players: players && players.players.length > 0 ? players : undefined, page, country, }; - rankingCache.set(cacheId, rankingData); - return rankingData; -}; +}); export async function generateMetadata(props: Props): Promise { const { players, page, country } = await getRankingData(props);