diff --git a/packages/hydrojudge/src/hosts/builtin.ts b/packages/hydrojudge/src/hosts/builtin.ts index 275742d7a..dcc32e849 100644 --- a/packages/hydrojudge/src/hosts/builtin.ts +++ b/packages/hydrojudge/src/hosts/builtin.ts @@ -28,7 +28,7 @@ const session = { data.rid = t.rid as any; const rdoc = await RecordModel.get(new ObjectId(t.rid)); if (data.case) data.case.message ||= ''; - next({ ...data, rdoc }); + next({ ...data, domainId: rdoc.domainId }); }; }, getEnd(t: Context) { @@ -37,7 +37,7 @@ const session = { data.rid = t.rid as any; const rdoc = await RecordModel.get(new ObjectId(t.rid)); logger.info('End: status=%d score=%d time=%dms memory=%dkb', data.status, data.score, data.time, data.memory); - end({ ...data, rdoc }); + end({ ...data, domainId: rdoc.domainId }); }; }, getLang(lang: string, doThrow = true) { diff --git a/packages/hydrojudge/src/hosts/hydro.ts b/packages/hydrojudge/src/hosts/hydro.ts index ac1617a4e..39f0c8a9f 100644 --- a/packages/hydrojudge/src/hosts/hydro.ts +++ b/packages/hydrojudge/src/hosts/hydro.ts @@ -166,6 +166,8 @@ export default class Hydro implements Session { if (performanceMode && data.case && !data.compilerText && !data.message) { t.callbackCache ||= []; t.callbackCache.push(data.case); + // TODO use rate-limited send + // FIXME handle fields like score, time, memory, etc } else { this.send(t.request.rid, 'next', data); } diff --git a/packages/hydrojudge/src/judge/run.ts b/packages/hydrojudge/src/judge/run.ts index 87b230fd2..b677137fc 100644 --- a/packages/hydrojudge/src/judge/run.ts +++ b/packages/hydrojudge/src/judge/run.ts @@ -57,5 +57,10 @@ export const judge = async (ctx: JudgeTask) => { } ctx.stat.done = new Date(); if (process.env.DEV) ctx.next({ message: JSON.stringify(ctx.stat) }); - ctx.end({ status }); + ctx.end({ + status, + time: Math.floor(time * 1000000) / 1000000, + memory, + score: status === STATUS.STATUS_ACCEPTED ? 100 : 0, + }); }; diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index 2ec93f9db..e26431162 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -41,24 +41,20 @@ function parseCaseResult(body: TestCase): Required { }; } -function processPayload(rdoc: RecordDoc, body: Partial) { +function processPayload(body: Partial) { const $set: Partial = {}; const $push: any = {}; if (body.cases?.length) { const c = body.cases.map(parseCaseResult); - rdoc.testCases.push(...c); $push.testCases = { $each: c }; } else if (body.case) { const c = parseCaseResult(body.case); - rdoc.testCases.push(c); $push.testCases = c; } 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; @@ -70,17 +66,10 @@ function processPayload(rdoc: RecordDoc, body: Partial) { return { $set, $push }; } -export async function next(body: Partial & { rdoc: RecordDoc }) { +export async function next(body: Partial) { body.rid = new ObjectId(body.rid); - let rdoc = body.rdoc; - if (!rdoc) { - logger.warn('Next function without rdoc is deprecated.'); - console.trace(); - rdoc = await record.get(body.rid); - if (!rdoc) return null; - } - const { $set, $push } = processPayload(rdoc, body); - rdoc = await record.update(rdoc.domainId, body.rid, $set, $push, {}, body.addProgress ? { progress: body.addProgress } : {}); + const { $set, $push } = processPayload(body); + const rdoc = await record.update(body.domainId, body.rid, $set, $push, {}, body.addProgress ? { progress: body.addProgress } : {}); bus.broadcast('record/change', rdoc, $set, $push, body); return rdoc; } @@ -137,7 +126,6 @@ export async function postJudge(rdoc: RecordDoc) { domainId: rdoc.domainId, key: 'next', message: { message: 'Unable to apply hack: {0}', params: [e.message] }, - rdoc, }); } } @@ -145,21 +133,14 @@ export async function postJudge(rdoc: RecordDoc) { await bus.parallel('record/judge', rdoc, updated); } -export async function end(body: Partial & { rdoc: RecordDoc }) { +export async function end(body: Partial) { body.rid = new ObjectId(body.rid); - let rdoc = body.rdoc; - if (!rdoc) { - logger.warn('End function without rdoc is deprecated.'); - console.trace(); - rdoc = await record.get(body.rid); - if (!rdoc) return null; - } - const { $set, $push } = processPayload(rdoc, body); + const { $set, $push } = processPayload(body); const $unset: any = { progress: '' }; $set.judgeAt = new Date(); $set.judger = body.judger ?? 1; await sleep(100); // Make sure that all 'next' event already triggered - rdoc = await record.update(rdoc.domainId, body.rid, $set, $push, $unset); + let rdoc = await record.update(body.domainId, body.rid, $set, $push, $unset); await postJudge(rdoc); rdoc = await record.get(body.rid); bus.broadcast('record/change', rdoc, null, null, body); // trigger a full update @@ -283,9 +264,9 @@ class JudgeConnectionHandler extends ConnectionHandler { if (['next', 'end'].includes(msg.key)) { const rdoc = this.rdocs[msg.rid]; if (!rdoc) return; - if (msg.key === 'next') await next({ ...msg, rdoc }); + if (msg.key === 'next') await next({ ...message, domainId: rdoc.domainId }); if (msg.key === 'end') { - if (!msg.nop) await end({ judger: this.user._id, ...msg, rdoc }).catch((e) => logger.error(e)); + if (!msg.nop) await end({ judger: this.user._id, ...msg, domainId: rdoc.domainId }).catch((e) => logger.error(e)); this.processing = this.processing.filter((t) => t.rid.toHexString() !== msg.rid); delete this.rdocs[msg.rid]; await this.newTask();