make loading beatsaver map hashes way faster
All checks were successful
deploy / deploy (push) Successful in 2m9s
All checks were successful
deploy / deploy (push) Successful in 2m9s
This commit is contained in:
parent
14f67af125
commit
b3c3be4b7c
@ -5,35 +5,61 @@ import { BeatsaverAPI } from "@/utils/beatsaver/api";
|
||||
export async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const mapHashes = searchParams.get("hashes")?.split(",") ?? undefined;
|
||||
|
||||
if (!mapHashes) {
|
||||
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) {
|
||||
|
||||
const fetchMapFromCache = async (mapHash: string) => {
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
maps[mapHash] = map;
|
||||
return cachedMap;
|
||||
};
|
||||
|
||||
const fetchAndCacheMap = async (mapHash: string) => {
|
||||
const beatSaverMap = await BeatsaverAPI.fetchMapByHash(mapHash);
|
||||
if (beatSaverMap) {
|
||||
maps[mapHash] = idOnly ? { id: beatSaverMap.id } : beatSaverMap;
|
||||
await (
|
||||
await Redis.client
|
||||
).set("beatsaver:map:" + mapHash, JSON.stringify(map), {
|
||||
EX: 60 * 60 * 24 * 7, // 7 days
|
||||
});
|
||||
).set(
|
||||
`beatsaver:map:${mapHash}`,
|
||||
JSON.stringify(idOnly ? { id: beatSaverMap.id } : beatSaverMap),
|
||||
"EX",
|
||||
60 * 60 * 24 * 7,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (idOnly) {
|
||||
maps[mapHash] = { id: (maps[mapHash] as BeatsaverMap).id };
|
||||
for (const mapHash of mapHashes) {
|
||||
const map = await fetchMapFromCache(mapHash);
|
||||
if (map) {
|
||||
maps[mapHash] = JSON.parse(map);
|
||||
totalInCache++;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalInCache === 0) {
|
||||
const beatSaverMaps = await BeatsaverAPI.fetchMapsByHash(...mapHashes);
|
||||
if (beatSaverMaps) {
|
||||
for (const mapHash of mapHashes) {
|
||||
const beatSaverMap = beatSaverMaps[mapHash.toLowerCase()];
|
||||
if (beatSaverMap) {
|
||||
await fetchAndCacheMap(mapHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const mapHash of mapHashes) {
|
||||
if (!maps[mapHash]) {
|
||||
await fetchAndCacheMap(mapHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,15 +10,40 @@ export const BeatsaverFetchQueue = new FetchQueue();
|
||||
const BS_API_URL = ssrSettings.proxy + "/https://api.beatsaver.com";
|
||||
export const BS_GET_MAP_BY_HASH_URL = BS_API_URL + "/maps/hash/{}";
|
||||
|
||||
/**
|
||||
* Returns the map info for the provided hashes
|
||||
*
|
||||
* @param hash the hashes for the maps
|
||||
* @returns the map info
|
||||
*/
|
||||
async function fetchMapsByHash(
|
||||
...hash: string[]
|
||||
): Promise<{ [key: string]: BeatsaverMap } | undefined> {
|
||||
const hashes = hash.join(",");
|
||||
const response = await BeatsaverFetchQueue.fetch(
|
||||
formatString(
|
||||
BS_GET_MAP_BY_HASH_URL,
|
||||
true,
|
||||
hashes.substring(0, hashes.length - 1),
|
||||
),
|
||||
);
|
||||
const json = await response.json();
|
||||
|
||||
// Check if there was an error fetching the user data
|
||||
if (json.error) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map info for the provided hash
|
||||
*
|
||||
* @param hash the hash of the map
|
||||
* @returns the map info
|
||||
*/
|
||||
async function fetchMapByHash(
|
||||
hash: string,
|
||||
): Promise<BeatsaverMap | undefined | null> {
|
||||
async function fetchMapByHash(hash: string): Promise<BeatsaverMap | undefined> {
|
||||
const response = await BeatsaverFetchQueue.fetch(
|
||||
formatString(BS_GET_MAP_BY_HASH_URL, true, hash),
|
||||
);
|
||||
@ -29,9 +54,10 @@ async function fetchMapByHash(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return json as BeatsaverMap;
|
||||
return json;
|
||||
}
|
||||
|
||||
export const BeatsaverAPI = {
|
||||
fetchMapsByHash,
|
||||
fetchMapByHash,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user