Skip to content

Commit ea6bc0b

Browse files
committed
core: fix judge race condition
1 parent d4b5d54 commit ea6bc0b

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

packages/hydrooj/src/handler/judge.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import sanitize from 'sanitize-filename';
77
import {
88
JudgeMeta, JudgeResultBody, ProblemConfigFile, TestCase,
99
} from '@hydrooj/common';
10+
import { sleep } from '@hydrooj/utils';
1011
import { Context } from '../context';
1112
import {
1213
BadRequestError, FileLimitExceededError, ForbiddenError, ProblemIsReferencedError, ValidationError,
@@ -281,7 +282,18 @@ export class JudgeConnectionHandler extends ConnectionHandler {
281282

282283
async newTask(t: Task) {
283284
const rid = t.rid.toHexString();
284-
this.tasks[rid] = new JudgeResultCallbackContext(this.ctx, t);
285+
const context = new JudgeResultCallbackContext(this.ctx, t);
286+
if (this.tasks[rid]) {
287+
for (let i = 1; i <= 300; i++) {
288+
if (!this.tasks[rid]) break;
289+
if (i === 300) {
290+
context.end({ message: 'Wait for previous judge timeout', status: STATUS.STATUS_SYSTEM_ERROR });
291+
return;
292+
}
293+
await sleep(1000); // eslint-disable-line no-await-in-loop
294+
}
295+
}
296+
this.tasks[rid] = context;
285297
this.send({ task: t });
286298
this.tasks[rid].next({ status: STATUS.STATUS_FETCHED });
287299
await this.tasks[rid];
@@ -296,7 +308,10 @@ export class JudgeConnectionHandler extends ConnectionHandler {
296308
}
297309
if (['next', 'end'].includes(msg.key)) {
298310
const t = this.tasks[msg.rid];
299-
if (!t) return;
311+
if (!t) {
312+
logger.warn('Unknown judge rid reported: %s', msg.rid);
313+
return;
314+
}
300315
if (msg.key === 'next') t.next(msg);
301316
if (msg.key === 'end') t.end(msg.nop ? undefined : { judger: this.user._id, ...msg });
302317
} else if (msg.key === 'status') {

0 commit comments

Comments
 (0)