switch to a different cache with a ttl
Some checks failed
Fix bun lock file / build (push) Successful in 41s
Deploy Website / deploy (push) Failing after 2m28s

This commit is contained in:
Lee 2024-10-09 17:56:17 +01:00
parent ee77a8f626
commit 2ebc04243c
5 changed files with 46 additions and 12 deletions

BIN
bun.lockb

Binary file not shown.

@ -9,7 +9,6 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@ssr/common": "workspace:*",
"@formkit/tempo": "^0.1.2", "@formkit/tempo": "^0.1.2",
"@heroicons/react": "^2.1.5", "@heroicons/react": "^2.1.5",
"@hookform/resolvers": "^3.9.0", "@hookform/resolvers": "^3.9.0",
@ -21,6 +20,7 @@
"@radix-ui/react-toast": "^1.2.1", "@radix-ui/react-toast": "^1.2.1",
"@radix-ui/react-tooltip": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.2",
"@sentry/nextjs": "8", "@sentry/nextjs": "8",
"@ssr/common": "workspace:*",
"@tanstack/react-query": "^5.55.4", "@tanstack/react-query": "^5.55.4",
"@uidotdev/usehooks": "^2.4.1", "@uidotdev/usehooks": "^2.4.1",
"chart.js": "^4.4.4", "chart.js": "^4.4.4",
@ -36,6 +36,7 @@
"next": "15.0.0-rc.0", "next": "15.0.0-rc.0",
"next-build-id": "^3.0.0", "next-build-id": "^3.0.0",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"node-cache": "^5.1.2",
"react": "19.0.0-rc-d5bba18b-20241009", "react": "19.0.0-rc-d5bba18b-20241009",
"react-chartjs-2": "^5.2.0", "react-chartjs-2": "^5.2.0",
"react-dom": "19.0.0-rc-d5bba18b-20241009", "react-dom": "19.0.0-rc-d5bba18b-20241009",

@ -2,10 +2,11 @@ import { Metadata, Viewport } from "next";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { Colors } from "@/common/colors"; import { Colors } from "@/common/colors";
import { getAverageColor } from "@/common/image-utils"; import { getAverageColor } from "@/common/image-utils";
import { cache } from "react";
import { LeaderboardData } from "@/components/leaderboard/leaderboard-data"; import { LeaderboardData } from "@/components/leaderboard/leaderboard-data";
import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
import ScoreSaberLeaderboardScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-scores-page-token"; import ScoreSaberLeaderboardScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-scores-page-token";
import NodeCache from "node-cache";
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
const UNKNOWN_LEADERBOARD = { const UNKNOWN_LEADERBOARD = {
title: "ScoreSaber Reloaded - Unknown Leaderboard", title: "ScoreSaber Reloaded - Unknown Leaderboard",
@ -21,6 +22,14 @@ type Props = {
}>; }>;
}; };
type LeaderboardData = {
leaderboard: ScoreSaberLeaderboardToken | undefined;
scores: ScoreSaberLeaderboardScoresPageToken | undefined;
page: number;
};
const leaderboardCache = new NodeCache({ stdTTL: 60, checkperiod: 120 });
/** /**
* Gets the leaderboard data and scores * Gets the leaderboard data and scores
* *
@ -28,23 +37,30 @@ type Props = {
* @param fetchScores whether to fetch the scores * @param fetchScores whether to fetch the scores
* @returns the leaderboard data and scores * @returns the leaderboard data and scores
*/ */
const getLeaderboardData = cache(async ({ params }: Props, fetchScores: boolean = true) => { const getLeaderboardData = async ({ params }: Props, fetchScores: boolean = true) => {
const { slug } = await params; const { slug } = await params;
const id = slug[0]; // The leaderboard id const id = slug[0]; // The leaderboard id
const page = parseInt(slug[1]) || 1; // The page number const page = parseInt(slug[1]) || 1; // The page number
const cacheId = `${id}-${page}`;
if (leaderboardCache.has(cacheId)) {
return leaderboardCache.get(cacheId) as LeaderboardData;
}
const leaderboard = await scoresaberService.lookupLeaderboard(id); const leaderboard = await scoresaberService.lookupLeaderboard(id);
let scores: ScoreSaberLeaderboardScoresPageToken | undefined; let scores: ScoreSaberLeaderboardScoresPageToken | undefined;
if (fetchScores) { if (fetchScores) {
scores = await scoresaberService.lookupLeaderboardScores(id + "", page); scores = await scoresaberService.lookupLeaderboardScores(id + "", page);
} }
return { const leaderboardData = {
page: page, page: page,
leaderboard: leaderboard, leaderboard: leaderboard,
scores: scores, scores: scores,
}; };
}); leaderboardCache.set(cacheId, leaderboardData);
return leaderboardData;
};
export async function generateMetadata(props: Props): Promise<Metadata> { export async function generateMetadata(props: Props): Promise<Metadata> {
const { leaderboard } = await getLeaderboardData(props, false); const { leaderboard } = await getLeaderboardData(props, false);

@ -5,13 +5,13 @@ import { Metadata, Viewport } from "next";
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { Colors } from "@/common/colors"; import { Colors } from "@/common/colors";
import { getAverageColor } from "@/common/image-utils"; import { getAverageColor } from "@/common/image-utils";
import { cache } from "react";
import { ScoreSort } from "@ssr/common/types/score/score-sort"; import { ScoreSort } from "@ssr/common/types/score/score-sort";
import { scoresaberService } from "@ssr/common/service/impl/scoresaber"; import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-player-scores-page-token"; import ScoreSaberPlayerScoresPageToken from "@ssr/common/types/token/scoresaber/score-saber-player-scores-page-token";
import { getScoreSaberPlayerFromToken } from "@ssr/common/types/player/impl/scoresaber-player"; import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/types/player/impl/scoresaber-player";
import { config } from "../../../../../config"; import { config } from "../../../../../config";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
import NodeCache from "node-cache";
const UNKNOWN_PLAYER = { const UNKNOWN_PLAYER = {
title: "ScoreSaber Reloaded - Unknown Player", title: "ScoreSaber Reloaded - Unknown Player",
@ -27,6 +27,16 @@ type Props = {
}>; }>;
}; };
type PlayerData = {
player: ScoreSaberPlayer | undefined;
scores: ScoreSaberPlayerScoresPageToken | undefined;
sort: ScoreSort;
page: number;
search: string;
};
const playerCache = new NodeCache({ stdTTL: 60, checkperiod: 120 });
/** /**
* Gets the player data and scores * Gets the player data and scores
* *
@ -34,13 +44,18 @@ type Props = {
* @param fetchScores whether to fetch the scores * @param fetchScores whether to fetch the scores
* @returns the player data and scores * @returns the player data and scores
*/ */
const getPlayerData = cache(async ({ params }: Props, fetchScores: boolean = true) => { const getPlayerData = async ({ params }: Props, fetchScores: boolean = true): Promise<PlayerData> => {
const { slug } = await params; const { slug } = await params;
const id = slug[0]; // The players id const id = slug[0]; // The players id
const sort: ScoreSort = (slug[1] as ScoreSort) || "recent"; // The sorting method const sort: ScoreSort = (slug[1] as ScoreSort) || "recent"; // The sorting method
const page = parseInt(slug[2]) || 1; // The page number const page = parseInt(slug[2]) || 1; // The page number
const search = (slug[3] as string) || ""; // The search query const search = (slug[3] as string) || ""; // The search query
const cacheId = `${id}-${sort}-${page}-${search}`;
if (playerCache.has(cacheId)) {
return playerCache.get(cacheId) as PlayerData;
}
const playerToken = await scoresaberService.lookupPlayer(id); const playerToken = await scoresaberService.lookupPlayer(id);
const player = const player =
playerToken && (await getScoreSaberPlayerFromToken(playerToken, config.siteApi, cookies().get("playerId")?.value)); playerToken && (await getScoreSaberPlayerFromToken(playerToken, config.siteApi, cookies().get("playerId")?.value));
@ -54,14 +69,16 @@ const getPlayerData = cache(async ({ params }: Props, fetchScores: boolean = tru
}); });
} }
return { const playerData = {
sort: sort, sort: sort,
page: page, page: page,
search: search, search: search,
player: player, player: player,
scores: scores, scores: scores,
}; };
}); playerCache.set(cacheId, playerData);
return playerData;
};
export async function generateMetadata(props: Props): Promise<Metadata> { export async function generateMetadata(props: Props): Promise<Metadata> {
const { player } = await getPlayerData(props, false); const { player } = await getPlayerData(props, false);

@ -17,8 +17,8 @@ export function getImageUrl(originalUrl: string) {
* @param src the image url * @param src the image url
* @returns the average color * @returns the average color
*/ */
export const getAverageColor = cache(async (src: string) => { export const getAverageColor = async (src: string) => {
return { return {
hex: "#fff", hex: "#fff",
}; };
}); };