switch to a different cache with a ttl
This commit is contained in:
parent
ee77a8f626
commit
2ebc04243c
BIN
bun.lockb
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",
|
||||||
};
|
};
|
||||||
});
|
};
|
||||||
|
Reference in New Issue
Block a user