diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index fe2f88391..be3e41c57 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.13.10", + "version": "2.13.11", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 274355b40..d9dffcac0 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -72,6 +72,7 @@ class ProblemMainHandler extends ProblemHandler { path.push([q, null, null, true]); } if (!this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)) query.hidden = false; + await bus.serial('problem/list', query, this); const [pdocs, ppcount, pcount] = await paginate( problem.getMulti(domainId, query).sort({ pid: 1, docId: 1 }), page, @@ -116,6 +117,7 @@ class ProblemCategoryHandler extends ProblemHandler { } let psdict = {}; if (!this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)) q.hidden = false; + await bus.serial('problem/list', q, this); const [pdocs, ppcount, pcount] = await paginate( problem.getMulti(domainId, q).sort({ pid: 1, docId: 1 }), page, @@ -152,6 +154,7 @@ class ProblemRandomHandler extends ProblemHandler { } } if (!this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)) q.hidden = false; + await bus.serial('problem/list', q, this); const pid = await problem.random(domainId, q); if (!pid) throw new NoProblemError(); this.response.body = { pid }; @@ -172,6 +175,7 @@ class ProblemDetailHandler extends ProblemHandler { if (this.pdoc.hidden && this.pdoc.owner !== this.user._id) { this.checkPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN); } + await bus.serial('problem/get', this.pdoc, this); this.udoc = await user.getById(domainId, this.pdoc.owner); this.response.body = { pdoc: this.pdoc, @@ -185,9 +189,6 @@ class ProblemDetailHandler extends ProblemHandler { }; } - // eslint-disable-next-line - async get(...args: any[]) { } - @param('pid', Types.UnsignedInt) @param('dest', Types.String) @param('hidden', Types.Boolean) diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 8aadd345a..b72da173a 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -435,7 +435,8 @@ export interface JudgeResultBody { export interface Task { _id: ObjectID, type: string, - executeAfter?: Date + executeAfter?: Date, + priority: number, [key: string]: any } diff --git a/packages/hydrooj/src/model/task.ts b/packages/hydrooj/src/model/task.ts index a10da5769..d334aa66b 100644 --- a/packages/hydrooj/src/model/task.ts +++ b/packages/hydrooj/src/model/task.ts @@ -1,14 +1,18 @@ import moment from 'moment-timezone'; -import { ObjectID } from 'mongodb'; +import { FilterQuery, ObjectID } from 'mongodb'; +import { Task } from '../interface'; import * as db from '../service/db'; const coll = db.collection('task'); -export async function add(task: any) { - const t = { ...task }; - if (typeof t.executeAfter === 'object') t.executeAfter = t.executeAfter.getTime(); - t.count = t.count || 1; - t.executeAfter = t.executeAfter || new Date().getTime(); +export async function add(task: Partial & { type: string }) { + const t: Task = { + ...task, + count: task.count || 1, + priority: task.priority || 1, + executeAfter: task.executeAfter || new Date(), + _id: new ObjectID(), + }; const res = await coll.insertOne(t); return res.insertedId; } @@ -17,7 +21,7 @@ export function get(_id: ObjectID) { return coll.findOne({ _id }); } -export function count(query: any) { +export function count(query: FilterQuery) { return coll.find(query).count(); } @@ -25,9 +29,9 @@ export function del(_id: ObjectID) { return coll.deleteOne({ _id }); } -export async function getFirst(query: any) { +export async function getFirst(query: FilterQuery) { const q = { ...query }; - q.executeAfter = q.executeAfter || { $lt: new Date().getTime() }; + q.executeAfter = q.executeAfter || { $lt: new Date() }; const res = await coll.findOneAndDelete(q); if (res.value) { if (res.value.interval) { diff --git a/packages/hydrooj/src/model/token.ts b/packages/hydrooj/src/model/token.ts index f508ce5c6..e76a75c8f 100644 --- a/packages/hydrooj/src/model/token.ts +++ b/packages/hydrooj/src/model/token.ts @@ -1,9 +1,8 @@ -import { Collection } from 'mongodb'; import { TokenDoc } from '../interface'; import * as db from '../service/db'; import * as bus from '../service/bus'; -export const coll: Collection = db.collection('token'); +export const coll = db.collection('token'); export const TYPE_SESSION = 0; export const TYPE_REGISTRATION = 2; diff --git a/packages/hydrooj/src/model/training.ts b/packages/hydrooj/src/model/training.ts index 0462f82d8..a9bc14b6d 100644 --- a/packages/hydrooj/src/model/training.ts +++ b/packages/hydrooj/src/model/training.ts @@ -8,7 +8,7 @@ export function getStatus(domainId: string, tid: ObjectID, uid: number) { return document.getStatus(domainId, document.TYPE_TRAINING, tid, uid); } -export function getMultiStatus(domainId: string, query: any) { +export function getMultiStatus(domainId: string, query: FilterQuery) { return document.getMultiStatus(domainId, document.TYPE_TRAINING, query); } diff --git a/packages/hydrooj/src/model/user.ts b/packages/hydrooj/src/model/user.ts index a2a80ca86..4ee4314e5 100644 --- a/packages/hydrooj/src/model/user.ts +++ b/packages/hydrooj/src/model/user.ts @@ -102,6 +102,8 @@ export class User implements _User { this[key] = setting.DOMAIN_USER_SETTINGS_BY_KEY[key].value; } } + + bus.serial('user/get', this); } hasPerm(...perm: bigint[]) { diff --git a/packages/hydrooj/src/service/bus.ts b/packages/hydrooj/src/service/bus.ts index 93b2d6bf3..94cec9dae 100644 --- a/packages/hydrooj/src/service/bus.ts +++ b/packages/hydrooj/src/service/bus.ts @@ -1,8 +1,10 @@ /* eslint-disable no-await-in-loop */ import cluster from 'cluster'; -import { Db } from 'mongodb'; +import { Db, FilterQuery } from 'mongodb'; import { Logger } from '../logger'; -import { Mdoc, Rdoc, User } from '../interface'; +import { + Mdoc, Pdoc, Rdoc, User, +} from '../interface'; type DocType = import('../model/document').DocType; @@ -14,6 +16,7 @@ function isBailed(value: any) { } export type Disposable = () => void +export type VoidReturn = Promise | void export interface EventMap { 'app/started': () => void @@ -22,11 +25,18 @@ export interface EventMap { 'database/connect': (db: Db) => void - 'user/message': (uid: number, mdoc: Mdoc, udoc: User) => void + 'monitor/update': (type: 'server' | 'judger', $set: any) => VoidReturn - 'document/add': (doc: any) => Promise | void + 'user/message': (uid: number, mdoc: Mdoc, udoc: User) => void + 'user/get': (udoc: User) => void + + 'document/add': (doc: any) => VoidReturn 'document/set': - (domainId: string, docType: T, docId: DocType[T], $set: any) => Promise | void + (domainId: string, docType: T, docId: DocType[T], $set: any) => VoidReturn + + 'problem/edit': (doc: Pdoc) => VoidReturn + 'problem/list': (query: FilterQuery, handler: any) => VoidReturn + 'problem/get': (doc: Pdoc, handler: any) => VoidReturn 'record/change': (rdoc: Rdoc, $set?: any, $push?: any) => void } diff --git a/packages/hydrooj/src/service/monitor.ts b/packages/hydrooj/src/service/monitor.ts index 097ced519..20fd2a1f8 100644 --- a/packages/hydrooj/src/service/monitor.ts +++ b/packages/hydrooj/src/service/monitor.ts @@ -7,19 +7,23 @@ const coll = db.collection('status'); export async function update() { const [mid, $set] = await sysinfo.update(); + $set.updateAt = new Date(); + $set.reqCount = global.Hydro.stat.reqCount; + await bus.serial('monitor/update', 'server', $set); await coll.updateOne( { mid, type: 'server' }, - { $set: { ...$set, updateAt: new Date(), reqCount: global.Hydro.stat.reqCount } }, + { $set }, { upsert: true }, ); global.Hydro.stat.reqCount = 0; } -export function updateJudger(args) { - args.type = 'judger'; - return coll.updateOne( +export async function updateJudger(args) { + const $set = { ...args, updateAt: new Date() }; + await bus.serial('monitor/update', 'judger', $set); + return await coll.updateOne( { mid: args.mid, type: 'judger' }, - { $set: { ...args, updateAt: new Date() } }, + { $set }, { upsert: true }, ); }