You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/packages/hydrooj/src/model/opcount.ts

29 lines
988 B
TypeScript

import { OpcountExceededError } from '../error';
import * as bus from '../service/bus';
import db from '../service/db';
5 years ago
const coll = db.collection('opcount');
export async function inc(op: string, ident: string, periodSecs: number, maxOperations: number) {
const now = new Date().getTime();
const expireAt = new Date(now - (now % (periodSecs * 1000)) + periodSecs * 1000);
4 years ago
try {
await coll.findOneAndUpdate({
op,
4 years ago
ident,
expireAt,
opcount: { $lt: maxOperations },
}, { $inc: { opcount: 1 } }, { upsert: true });
4 years ago
} catch (e) {
if (e.message.includes('duplicate')) throw new OpcountExceededError(op, periodSecs, maxOperations);
throw e;
4 years ago
}
}
bus.once('app/started', () => db.ensureIndexes(
coll,
{ key: { expireAt: -1 }, name: 'expire', expireAfterSeconds: 0 },
{ key: { op: 1, ident: 1, expireAt: 1 }, name: 'unique', unique: true },
));
global.Hydro.model.opcount = { inc };