judge: use compileInteractor and per file cleanup

This commit is contained in:
undefined committed 2022-09-06 13:02:46 +08:00
1 parent 15ea8232a8
commit 5e113d9c7e
5 files changed
+52 -27

No files matched your search

+8 -1
View File
@@ -43,7 +43,7 @@ export default async function compile(
}
const testlibFile = {
src: findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h')
src: findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h'),
};
const guessLanguage = (filename: string, getLang: Function) => {
@@ -70,6 +70,13 @@ export async function compileChecker(getLang: Function, checkerType: string, che
return await compile(lang, { src: checker }, copyIn);
}
export async function compileInteractor(getLang: Function, interactor: string, copyIn: any): Promise<Execute> {
const lang = guessLanguage(interactor, getLang);
if (!lang) throw new FormatError('Unknown interactor language.');
// TODO cache compiled checker
return await compile(lang, { src: interactor }, { ...copyIn, 'testlib.h': testlibFile });
}
export async function compileValidator(getLang: Function, validator: string, copyIn: any): Promise<Execute> {
const lang = guessLanguage(validator, getLang);
if (!lang) throw new FormatError('Unknown validator language.');
+7 -3
View File
@@ -3,6 +3,7 @@ import { STATUS } from '@hydrooj/utils/lib/status';
import checkers from '../checkers';
import compile, { compileChecker } from '../compile';
import { runFlow } from '../flow';
import { Execute } from '../interface';
import { Logger } from '../log';
import { CmdFile, del, run } from '../sandbox';
import signals from '../signals';
@@ -121,6 +122,10 @@ function judgeCase(c: NormalizedCase, sid: string) {
export const judge = async (ctx: Context) => await runFlow(ctx, {
compile: async () => {
const markCleanup = (i: Execute) => {
ctx.clean.push(i.clean);
return i;
};
[ctx.execute, ctx.checker] = await Promise.all([
compile(
ctx.session.getLang(ctx.lang), ctx.code,
@@ -128,7 +133,7 @@ export const judge = async (ctx: Context) => await runFlow(ctx, {
(ctx.config.user_extra_files || []).map((i) => [i.split('/').pop(), { src: i }]),
),
ctx.next,
),
).then(markCleanup),
compileChecker(
ctx.session.getLang,
ctx.config.checker_type,
@@ -139,9 +144,8 @@ export const judge = async (ctx: Context) => await runFlow(ctx, {
(ctx.config.judge_extra_files || []).map((i) => [basename(i), { src: i }]),
),
},
),
).then(markCleanup),
]);
ctx.clean.push(ctx.execute.clean, ctx.checker.clean);
},
judgeCase,
});
+18 -22
View File
@@ -1,7 +1,8 @@
import { basename } from 'path';
import { STATUS } from '@hydrooj/utils/lib/status';
import compile from '../compile';
import compile, { compileInteractor } from '../compile';
import { runFlow } from '../flow';
import { Execute } from '../interface';
import { runPiped } from '../sandbox';
import signals from '../signals';
import { parse } from '../testlib';
@@ -76,28 +77,23 @@ function judgeCase(c: NormalizedCase) {
export const judge = async (ctx: Context) => await runFlow(ctx, {
compile: async () => {
const markCleanup = (i: Execute) => {
ctx.clean.push(i.clean);
return i;
};
const userExtraFiles = Object.fromEntries(
(ctx.config.user_extra_files || []).map((i) => [basename(i), { src: i }]),
);
const interactorFiles = {
'testlib.h': { src: testlibSrc },
user_code: ctx.code,
};
for (const file of ctx.config.judge_extra_files) {
interactorFiles[basename(file)] = { src: file };
}
[ctx.executeUser, ctx.executeInteractor] = await Promise.all([
(() => {
const copyIn = {};
for (const file of ctx.config.user_extra_files) {
copyIn[basename(file)] = { src: file };
}
return compile(ctx.session.getLang(ctx.lang), ctx.code, copyIn, ctx.next);
})(),
(() => {
const copyIn = {
'testlib.h': { src: testlibSrc },
user_code: ctx.code,
};
for (const file of ctx.config.judge_extra_files) {
copyIn[basename(file)] = { src: file };
}
return compile(
ctx.session.getLang(basename(ctx.config.interactor).split('.')[1].replace('@', '.')),
{ src: ctx.config.interactor },
copyIn,
);
})(),
compile(ctx.session.getLang(ctx.lang), ctx.code, userExtraFiles, ctx.next).then(markCleanup),
compileInteractor(ctx.session.getLang, ctx.config.interactor, interactorFiles).then(markCleanup),
]);
ctx.clean.push(ctx.executeUser.clean, ctx.executeInteractor.clean);
},