core&judge: allow performance mode

This commit is contained in:
undefined committed 2023-02-24 19:26:41 +08:00
1 parent 080621738e
commit 4adf05c50b
5 files changed
+40 -31

No files matched your search

+1
View File
@@ -26,6 +26,7 @@ const JudgeSettings = Schema.object({
secret: Schema.string().description('Judge Token Secret').default(String.random(32)), secret: Schema.string().description('Judge Token Secret').default(String.random(32)),
disable: Schema.boolean().description('Disable builtin judge').default(false), disable: Schema.boolean().description('Disable builtin judge').default(false),
detail: Schema.boolean().description('Show diff detail').default(true), detail: Schema.boolean().description('Show diff detail').default(true),
performance: Schema.boolean().description('Performance mode').default(false),
}); });
const oldPath = path.resolve(os.homedir(), '.config', 'hydro', 'judge.yaml'); const oldPath = path.resolve(os.homedir(), '.config', 'hydro', 'judge.yaml');
+6
View File
@@ -155,13 +155,19 @@ export default class Hydro {
getNext(t: JudgeTask) { getNext(t: JudgeTask) {
return (data: Partial<JudgeResultBody>) => { return (data: Partial<JudgeResultBody>) => {
log.debug('Next: %o', data); log.debug('Next: %o', data);
if (getConfig('performance') && data.case && !data.compilerText && !data.message) {
t.callbackCache ||= [];
t.callbackCache.push(data.case);
} else {
this.send(t.request.rid, 'next', data); this.send(t.request.rid, 'next', data);
}
}; };
} }
getEnd(t: JudgeTask) { getEnd(t: JudgeTask) {
return (data: Partial<JudgeResultBody>) => { return (data: Partial<JudgeResultBody>) => {
log.info('End: %o', data); log.info('End: %o', data);
if (t.callbackCache) data.cases = t.callbackCache;
this.send(t.request.rid, 'end', data); this.send(t.request.rid, 'end', data);
}; };
} }
+2 -1
View File
@@ -2,7 +2,7 @@ import fs from 'fs-extra';
import { LangConfig } from '@hydrooj/utils/lib/lang'; import { LangConfig } from '@hydrooj/utils/lib/lang';
import { STATUS } from '@hydrooj/utils/lib/status'; import { STATUS } from '@hydrooj/utils/lib/status';
import type { import type {
FileInfo, JudgeMeta, JudgeRequest, JudgeResultBody, FileInfo, JudgeMeta, JudgeRequest, JudgeResultBody, TestCase,
} from 'hydrooj'; } from 'hydrooj';
import readCases from './cases'; import readCases from './cases';
import { getConfig } from './config'; import { getConfig } from './config';
@@ -40,6 +40,7 @@ export class JudgeTask {
next: (data: Partial<JudgeResultBody>) => void; next: (data: Partial<JudgeResultBody>) => void;
end: (data: Partial<JudgeResultBody>) => void; end: (data: Partial<JudgeResultBody>) => void;
env: Record<string, string>; env: Record<string, string>;
callbackCache?: TestCase[];
constructor(public session: Session, public request: JudgeRequest) { constructor(public session: Session, public request: JudgeRequest) {
this.stat = {}; this.stat = {};
+29 -29
View File
@@ -24,20 +24,25 @@ import { sleep } from '../utils';
const logger = new Logger('judge'); const logger = new Logger('judge');
export async function next(body: Partial<JudgeResultBody>) { function parseCaseResult(body: TestCase): Required<TestCase> {
body.rid = new ObjectID(body.rid); return {
let rdoc = await record.get(body.rid); ...body,
if (!rdoc) return; id: body.id || 0,
subtaskId: body.subtaskId || 0,
score: body.score || 0,
message: body.message || '',
};
}
function processPayload(rdoc: RecordDoc, body: Partial<JudgeResultBody>) {
const $set: Partial<RecordDoc> = {}; const $set: Partial<RecordDoc> = {};
const $push: any = {}; const $push: any = {};
if (body.case) { if (body.cases?.length) {
const c: Required<TestCase> = { const c = body.cases.map(parseCaseResult);
...body.case, rdoc.testCases.push(...c);
id: body.case.id || 0, $push.testCases = { $each: c };
subtaskId: body.case.subtaskId || 0, } else if (body.case) {
score: body.case.score || 0, const c = parseCaseResult(body.case);
message: body.case.message || '',
};
rdoc.testCases.push(c); rdoc.testCases.push(c);
$push.testCases = c; $push.testCases = c;
} }
@@ -50,10 +55,18 @@ export async function next(body: Partial<JudgeResultBody>) {
$push.compilerTexts = body.compilerText; $push.compilerTexts = body.compilerText;
} }
if (body.status) $set.status = body.status; if (body.status) $set.status = body.status;
if (body.score !== undefined) $set.score = body.score; if (Number.isFinite(body.score)) $set.score = Math.floor(body.score * 100) / 100;
if (body.time !== undefined) $set.time = body.time; if (Number.isFinite(body.time)) $set.time = body.time;
if (body.memory !== undefined) $set.memory = body.memory; if (Number.isFinite(body.memory)) $set.memory = body.memory;
if (body.progress !== undefined) $set.progress = body.progress; if (body.progress !== undefined) $set.progress = body.progress;
return { $set, $push };
}
export async function next(body: Partial<JudgeResultBody>) {
body.rid = new ObjectID(body.rid);
let rdoc = await record.get(body.rid);
if (!rdoc) return;
const { $set, $push } = processPayload(rdoc, body);
rdoc = await record.update(rdoc.domainId, body.rid, $set, $push, {}, body.addProgress ? { progress: body.addProgress } : {}); rdoc = await record.update(rdoc.domainId, body.rid, $set, $push, {}, body.addProgress ? { progress: body.addProgress } : {});
bus.broadcast('record/change', rdoc!, $set, $push); bus.broadcast('record/change', rdoc!, $set, $push);
} }
@@ -118,21 +131,8 @@ export async function end(body: Partial<JudgeResultBody>) {
body.rid &&= new ObjectID(body.rid); body.rid &&= new ObjectID(body.rid);
let rdoc = await record.get(body.rid); let rdoc = await record.get(body.rid);
if (!rdoc) return; if (!rdoc) return;
const $set: Partial<RecordDoc> = {}; const { $set, $push } = processPayload(rdoc, body);
const $push: any = {};
const $unset: any = { progress: '' }; const $unset: any = { progress: '' };
if (body.message) {
rdoc.judgeTexts.push(body.message);
$push.judgeTexts = body.message;
}
if (body.compilerText) {
rdoc.compilerTexts.push(body.compilerText);
$push.compilerTexts = body.compilerText;
}
if (body.status) $set.status = body.status;
if (Number.isFinite(body.score)) $set.score = Math.floor(body.score * 100) / 100;
if (Number.isFinite(body.time)) $set.time = body.time;
if (Number.isFinite(body.memory)) $set.memory = body.memory;
$set.judgeAt = new Date(); $set.judgeAt = new Date();
$set.judger = body.judger ?? 1; $set.judger = body.judger ?? 1;
await sleep(100); // Make sure that all 'next' event already triggered await sleep(100); // Make sure that all 'next' event already triggered
+2 -1
View File
@@ -567,7 +567,8 @@ export interface JudgeResultBody {
judger?: number; judger?: number;
progress?: number; progress?: number;
addProgress?: number; addProgress?: number;
case?: TestCase, case?: TestCase;
cases?: TestCase[];
status?: number; status?: number;
score?: number; score?: number;
/** in miliseconds */ /** in miliseconds */