import { client, collections } from "$lib/server/database"; import { acquireLock, refreshLock } from "$lib/migrations/lock"; import type { ObjectId } from "mongodb"; import { subDays } from "date-fns"; import { logger } from "$lib/server/logger"; const LOCK_KEY = "assistants.count"; let hasLock = false; let lockId: ObjectId | null = null; async function refreshAssistantsCountsHelper() { if (!hasLock) { return; } try { await client.withSession((session) => session.withTransaction(async () => { await collections.assistants .aggregate([ { $project: { _id: 1 } }, { $set: { last24HoursCount: 0 } }, { $unionWith: { coll: "assistants.stats", pipeline: [ { $match: { "date.at": { $gte: subDays(new Date(), 1) }, "date.span": "hour" } }, { $group: { _id: "$assistantId", last24HoursCount: { $sum: "$count" }, }, }, ], }, }, { $group: { _id: "$_id", last24HoursCount: { $sum: "$last24HoursCount" }, }, }, { $merge: { into: "assistants", on: "_id", whenMatched: "merge", whenNotMatched: "discard", }, }, ]) .next(); }) ); } catch (e) { logger.error("Refresh assistants counter failed!"); logger.error(e); } } async function maintainLock() { if (hasLock && lockId) { hasLock = await refreshLock(LOCK_KEY, lockId); if (!hasLock) { lockId = null; } } else if (!hasLock) { lockId = (await acquireLock(LOCK_KEY)) || null; hasLock = !!lockId; } setTimeout(maintainLock, 10_000); } export function refreshAssistantsCounts() { const ONE_HOUR_MS = 3_600_000; maintainLock().then(() => { refreshAssistantsCountsHelper(); setInterval(refreshAssistantsCountsHelper, ONE_HOUR_MS); }); }