judge: allow minPriority config

This commit is contained in:
undefined committed 2021-04-22 13:01:36 +08:00
1 parent 936acf0139
commit b548a48b23
10 files changed
+22 -12

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@hydrooj/hydrojudge", "name": "@hydrooj/hydrojudge",
"bin": "bin/hydrojudge.js", "bin": "bin/hydrojudge.js",
"version": "2.5.10", "version": "2.5.11",
"main": "package.json", "main": "package.json",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"repository": "https://github.com/hydro-dev/Hydro.git", "repository": "https://github.com/hydro-dev/Hydro.git",
+1 -1
View File
@@ -244,7 +244,7 @@ export default class Hydro {
this.ws.send(this.config.cookie); this.ws.send(this.config.cookie);
global.onDestory.push(() => this.ws.close()); global.onDestory.push(() => this.ws.close());
setInterval(() => { setInterval(() => {
this.ws.send('{"event":"ping"}'); this.ws.send(`{"key":"prio","prio":${this.config.minPriority || -50}}`);
}, 30000); }, 30000);
}); });
this.ws.on('message', (data) => { this.ws.on('message', (data) => {
@@ -1,5 +1,6 @@
import Queue from 'p-queue'; import Queue from 'p-queue';
import fs from 'fs-extra'; import fs from 'fs-extra';
import { argv } from 'yargs';
import * as STATUS from '../status'; import * as STATUS from '../status';
import { parse } from '../testlib'; import { parse } from '../testlib';
import { findFileSync, parseFilename } from '../utils'; import { findFileSync, parseFilename } from '../utils';
+1
View File
@@ -243,6 +243,7 @@ async function postInit() {
} }
task.consume({ type: 'judge' }, (t) => (new JudgeTask(t)).handle().catch(logger.error)); task.consume({ type: 'judge' }, (t) => (new JudgeTask(t)).handle().catch(logger.error));
task.consume({ type: 'judge', priority: { $gt: -50 } }, (t) => (new JudgeTask(t)).handle().catch(logger.error));
} }
global.Hydro.service.bus.once('app/started', postInit); global.Hydro.service.bus.once('app/started', postInit);
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "hydrooj", "name": "hydrooj",
"version": "2.23.18", "version": "2.23.19",
"bin": "bin/hydrooj.js", "bin": "bin/hydrooj.js",
"main": "dist/loader.js", "main": "dist/loader.js",
"typings": "dist/loader.d.ts", "typings": "dist/loader.d.ts",
+4 -1
View File
@@ -118,6 +118,7 @@ export class JudgeFilesDownloadHandler extends Handler {
class JudgeConnectionHandler extends ConnectionHandler { class JudgeConnectionHandler extends ConnectionHandler {
processing: any = null; processing: any = null;
closed = false; closed = false;
query: any = { type: 'judge' };
async prepare() { async prepare() {
logger.info('Judge daemon connected from ', this.request.ip); logger.info('Judge daemon connected from ', this.request.ip);
@@ -132,7 +133,7 @@ class JudgeConnectionHandler extends ConnectionHandler {
await sleep(100); await sleep(100);
if (this.closed) return; if (this.closed) return;
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
t = await task.getFirst({ type: 'judge' }); t = await task.getFirst(this.query);
} }
this.send({ task: t }); this.send({ task: t });
this.processing = t; this.processing = t;
@@ -150,6 +151,8 @@ class JudgeConnectionHandler extends ConnectionHandler {
await this.newTask(); await this.newTask();
} else if (msg.key === 'status') { } else if (msg.key === 'status') {
await updateJudge(msg.info); await updateJudge(msg.info);
} else if (msg.key === 'prio') {
this.query.priority = { $gt: msg.prio };
} }
} }
+1 -1
View File
@@ -211,7 +211,7 @@ export class ProblemDetailHandler extends ProblemHandler {
// TODO maybe async? // TODO maybe async?
await record.getMulti(domainId, { pid }).forEach(async (doc) => { await record.getMulti(domainId, { pid }).forEach(async (doc) => {
await record.reset(domainId, doc._id, true); await record.reset(domainId, doc._id, true);
await record.judge(domainId, doc._id, -1); await record.judge(domainId, doc._id, -50);
}); });
this.back(); this.back();
} }
+10 -6
View File
@@ -16,11 +16,11 @@ import db from '../service/db';
class RecordModel { class RecordModel {
static coll: Collection<Rdoc> = db.collection('record'); static coll: Collection<Rdoc> = db.collection('record');
static async submissionPriority(uid: number) { static async submissionPriority(uid: number, base: number = 0) {
const pending = await task.count({ uid }); const pending = await task.count({ uid });
const timeRecent = await RecordModel.coll const timeRecent = await RecordModel.coll
.find({ _id: { $gte: Time.getObjectID(moment().add(-1, 'hour')) }, uid }).project({ time: 1 }).toArray(); .find({ _id: { $gte: Time.getObjectID(moment().add(-1, 'hour')) }, uid }).project({ time: 1 }).toArray();
return -(pending * (sum(timeRecent.map((i) => i.time || 0)) / 100000)); return base - ((pending + 0.5) * (sum(timeRecent.map((i) => i.time || 0)) / 10000));
} }
static async get(domainId: string, _id: ObjectID): Promise<Rdoc | null> { static async get(domainId: string, _id: ObjectID): Promise<Rdoc | null> {
@@ -45,7 +45,7 @@ class RecordModel {
}; };
} }
static async judge(domainId: string, rid: ObjectID, priority = 1, config: ProblemConfig = {}) { static async judge(domainId: string, rid: ObjectID, priority = 0, config: ProblemConfig = {}) {
const rdoc = await RecordModel.get(domainId, rid); const rdoc = await RecordModel.get(domainId, rid);
let data = []; let data = [];
if (rdoc.pid) { if (rdoc.pid) {
@@ -87,15 +87,19 @@ class RecordModel {
judgeAt: null, judgeAt: null,
rejudged: false, rejudged: false,
}; };
let isContest = false;
if (typeof contestOrConfig === 'string') { if (typeof contestOrConfig === 'string') {
// is Run // is Run
data.input = contestOrConfig; data.input = contestOrConfig;
data.hidden = true; data.hidden = true;
} else data.contest = contestOrConfig; } else {
data.contest = contestOrConfig;
isContest = true;
}
const res = await RecordModel.coll.insertOne(data); const res = await RecordModel.coll.insertOne(data);
if (addTask) { if (addTask) {
const priority = await RecordModel.submissionPriority(uid); const priority = await RecordModel.submissionPriority(uid, isContest ? 50 : 0);
await RecordModel.judge(domainId, res.insertedId, 1 + priority); await RecordModel.judge(domainId, res.insertedId, priority);
} }
return res.insertedId; return res.insertedId;
} }
+1 -1
View File
@@ -12,7 +12,7 @@ class TaskModel {
const t: Task = { const t: Task = {
...task, ...task,
count: task.count ?? 1, count: task.count ?? 1,
priority: task.priority ?? 1, priority: task.priority ?? 0,
executeAfter: task.executeAfter || new Date(), executeAfter: task.executeAfter || new Date(),
_id: new ObjectID(), _id: new ObjectID(),
}; };
+1
View File
@@ -296,6 +296,7 @@ export class HandlerCommon {
async limitRate(op: string, periodSecs: number, maxOperations: number) { async limitRate(op: string, periodSecs: number, maxOperations: number) {
if (this.user && this.user.hasPriv(PRIV.PRIV_UNLIMITED_ACCESS)) return; if (this.user && this.user.hasPriv(PRIV.PRIV_UNLIMITED_ACCESS)) return;
logger.info(op, periodSecs, maxOperations, this.request.ip);
await opcount.inc(op, this.request.ip, periodSecs, maxOperations); await opcount.inc(op, this.request.ip, periodSecs, maxOperations);
} }