monkeytype/backend/jobs/update-leaderboards.ts
Jack 6598823d60
Converted leaderboards DAO to typescript (#2843)
* added type for leaderboard entry

* converted leaderboards to ts

* fixed return type

* renamed occurences to DAL

* removed as any

* removed as any

* removed type casting
2022-04-21 12:24:13 +02:00

72 lines
2 KiB
TypeScript

import { CronJob } from "cron";
import BotDAO from "../dao/bot";
import George from "../tasks/george";
import * as LeaderboardsDAL from "../dao/leaderboards";
import { getCachedConfiguration } from "../init/configuration";
const CRON_SCHEDULE = "30 14/15 * * * *";
const RECENT_AGE_MINUTES = 10;
const RECENT_AGE_MILLISECONDS = RECENT_AGE_MINUTES * 60 * 1000;
async function getTop10(
leaderboardTime: string
): Promise<MonkeyTypes.LeaderboardEntry[]> {
return (await LeaderboardsDAL.get(
"time",
leaderboardTime,
"english",
0,
10
)) as MonkeyTypes.LeaderboardEntry[]; //can do that because gettop10 will not be called during an update
}
async function updateLeaderboardAndNotifyChanges(
leaderboardTime: string
): Promise<void> {
const top10BeforeUpdate = await getTop10(leaderboardTime);
const previousRecordsMap = Object.fromEntries(
top10BeforeUpdate.map((record) => {
return [record.uid, record];
})
);
await LeaderboardsDAL.update("time", leaderboardTime, "english");
const top10AfterUpdate = await getTop10(leaderboardTime);
const newRecords = top10AfterUpdate.filter((record) => {
const userId = record.uid;
const userImprovedRank =
userId in previousRecordsMap &&
previousRecordsMap[userId].rank > record.rank;
const newUserInTop10 = !(userId in previousRecordsMap);
const isRecentRecord =
record.timestamp > Date.now() - RECENT_AGE_MILLISECONDS;
return (userImprovedRank || newUserInTop10) && isRecentRecord;
});
if (newRecords.length > 0) {
const cachedConfig = await getCachedConfiguration();
const leaderboardId = `time ${leaderboardTime} english`;
if (cachedConfig.useRedisForBotTasks.enabled) {
await George.announceLbUpdate(newRecords, leaderboardId);
}
await BotDAO.announceLbUpdate(newRecords, leaderboardId);
}
}
async function updateLeaderboards(): Promise<void> {
await updateLeaderboardAndNotifyChanges("15");
await updateLeaderboardAndNotifyChanges("60");
}
export default new CronJob(CRON_SCHEDULE, updateLeaderboards);