|
import { client, collections } from "$lib/server/database"; |
|
import { acquireLock, refreshLock } from "$lib/migrations/lock"; |
|
import type { ObjectId } from "mongodb"; |
|
import { subDays } from "date-fns"; |
|
|
|
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) { |
|
console.log("Refresh assistants counter failed!"); |
|
console.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); |
|
}); |
|
} |
|
|