move beatsaver map caching to redis
All checks were successful
deploy / deploy (push) Successful in 1m35s
All checks were successful
deploy / deploy (push) Successful in 1m35s
This commit is contained in:
@ -1,7 +1,8 @@
|
||||
import { Redis } from "@/db/redis";
|
||||
import { BeatsaverMap } from "@/schemas/beatsaver/BeatsaverMap";
|
||||
import { BeatsaverAPI } from "@/utils/beatsaver/api";
|
||||
|
||||
const mapCache = new Map<string, BeatsaverMap>();
|
||||
await Redis.connectRedis();
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
@ -10,24 +11,41 @@ export async function GET(request: Request) {
|
||||
return new Response("mapHashes parameter is required", { status: 400 });
|
||||
}
|
||||
const idOnly = searchParams.get("idonly") === "true";
|
||||
let totalInCache = 0;
|
||||
|
||||
const maps: Record<string, BeatsaverMap | { id: string }> = {};
|
||||
for (const mapHash of mapHashes) {
|
||||
if (mapCache.has(mapHash)) {
|
||||
maps[mapHash] = mapCache.get(mapHash)!;
|
||||
const cachedMap = await (
|
||||
await Redis.client
|
||||
).get(`beatsaver:map:${mapHash}`);
|
||||
if (cachedMap) {
|
||||
maps[mapHash] = JSON.parse(cachedMap);
|
||||
totalInCache++;
|
||||
} else {
|
||||
const map = await BeatsaverAPI.fetchMapByHash(mapHash);
|
||||
if (map) {
|
||||
maps[mapHash] = map;
|
||||
mapCache.set(mapHash, map);
|
||||
}
|
||||
if (map && idOnly) {
|
||||
maps[mapHash] = { id: map.id };
|
||||
if (!map) {
|
||||
continue;
|
||||
}
|
||||
maps[mapHash] = map;
|
||||
await (
|
||||
await Redis.client
|
||||
).set("beatsaver:map:" + mapHash, JSON.stringify(map), {
|
||||
EX: 60 * 60 * 24 * 7, // 7 days
|
||||
});
|
||||
}
|
||||
|
||||
if (idOnly) {
|
||||
maps[mapHash] = { id: (maps[mapHash] as BeatsaverMap).id };
|
||||
}
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify(maps), {
|
||||
headers: { "content-type": "application/json;charset=UTF-8" },
|
||||
});
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
maps,
|
||||
totalInCache,
|
||||
}),
|
||||
{
|
||||
headers: { "content-type": "application/json;charset=UTF-8" },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -16,14 +16,14 @@ export default function BeatSaverLogo({
|
||||
version="1.1"
|
||||
className={className}
|
||||
>
|
||||
<g fill="none" stroke="#000000" stroke-width="10">
|
||||
<path d="M 100,7 189,47 100,87 12,47 Z" stroke-linejoin="round"></path>
|
||||
<g fill="none" stroke="#000000" strokeWidth="10">
|
||||
<path d="M 100,7 189,47 100,87 12,47 Z" strokeLinejoin="round"></path>
|
||||
<path
|
||||
d="M 189,47 189,155 100,196 12,155 12,47"
|
||||
stroke-linejoin="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<path d="M 100,87 100,196" stroke-linejoin="round"></path>
|
||||
<path d="M 26,77 85,106 53,130 Z" stroke-linejoin="round"></path>
|
||||
<path d="M 100,87 100,196" strokeLinejoin="round"></path>
|
||||
<path d="M 26,77 85,106 53,130 Z" strokeLinejoin="round"></path>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
31
src/db/redis.ts
Normal file
31
src/db/redis.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { createClient } from "redis";
|
||||
|
||||
let redisClient = connectRedis();
|
||||
|
||||
async function connectRedis() {
|
||||
console.log("Connecting to redis");
|
||||
const client = createClient({
|
||||
url: process.env.REDIS_URL,
|
||||
});
|
||||
await client.connect();
|
||||
|
||||
client.on("connect", () => {
|
||||
console.log("Connected to redis");
|
||||
});
|
||||
|
||||
client.on("error", (error) => {
|
||||
console.error("There was an error connecting to redis: " + error);
|
||||
setTimeout(() => {
|
||||
redisClient = connectRedis();
|
||||
}, 5_000); // 5 seconds
|
||||
});
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
// todo: add disconnect handler
|
||||
|
||||
export const Redis = {
|
||||
client: redisClient,
|
||||
connectRedis,
|
||||
};
|
@ -176,7 +176,7 @@ async function fetchScoresWithBeatsaverData(
|
||||
});
|
||||
const mapJson = await mapResponse.json();
|
||||
for (const score of scores) {
|
||||
const mapData = mapJson[score.leaderboard.songHash];
|
||||
const mapData = mapJson.maps[score.leaderboard.songHash];
|
||||
if (mapData) {
|
||||
scoresWithBeatsaverData[score.leaderboard.songHash] = {
|
||||
score: score.score,
|
||||
|
Reference in New Issue
Block a user