diff --git a/packages/hydrojudge/src/judge/default.ts b/packages/hydrojudge/src/judge/default.ts index 0f7b369a..a6eedf81 100644 --- a/packages/hydrojudge/src/judge/default.ts +++ b/packages/hydrojudge/src/judge/default.ts @@ -1,14 +1,11 @@ import { STATUS } from '@hydrooj/utils/lib/status'; import checkers from '../checkers'; import { runFlow } from '../flow'; -import { Logger } from '../log'; import { del, runQueued } from '../sandbox'; import signals from '../signals'; import { NormalizedCase } from '../utils'; import { Context, ContextSubTask } from './interface'; -const logger = new Logger('judge/default'); - function judgeCase(c: NormalizedCase) { return async (ctx: Context, ctxSubtask: ContextSubTask, runner?: Function) => { const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang); @@ -58,31 +55,9 @@ function judgeCase(c: NormalizedCase) { ctx.rerun--; return await runner(ctx, ctxSubtask); } - if (!ctx.request.rejudged && [STATUS.STATUS_WRONG_ANSWER, STATUS.STATUS_RUNTIME_ERROR].includes(status)) { - const langConfig = ctx.session.getLang(ctx.lang); - if (langConfig.analysis && !ctx.analysis) { - ctx.analysis = true; - try { - const r = await runQueued(langConfig.analysis, { - copyIn: { - ...ctx.execute.copyIn, - input: { src: c.input }, - [langConfig.code_file || 'foo']: ctx.code, - compile: { content: langConfig.compile || '' }, - execute: { content: langConfig.execute || '' }, - }, - time: 5000, - memory: 256, - env: ctx.env, - }); - const out = r.stdout.toString(); - if (out.length) ctx.next({ compilerText: out.substring(0, 1024) }); - if (process.env.DEV) console.log(r); - } catch (e) { - logger.info('Failed to run analysis'); - logger.error(e); - } - } + if (!ctx.request.rejudged && !ctx.analysis && [STATUS.STATUS_WRONG_ANSWER, STATUS.STATUS_RUNTIME_ERROR].includes(status)) { + ctx.analysis = true; + await ctx.runAnalysis(ctx.execute, { src: ctx.input }); } return { id: c.id, diff --git a/packages/hydrojudge/src/judge/run.ts b/packages/hydrojudge/src/judge/run.ts index 6a409977..222ea9ee 100644 --- a/packages/hydrojudge/src/judge/run.ts +++ b/packages/hydrojudge/src/judge/run.ts @@ -1,49 +1,16 @@ import { STATUS } from '@hydrooj/utils/lib/status'; -import { CompileError } from '../error'; -import { Execute } from '../interface'; import { Logger } from '../log'; import { runQueued } from '../sandbox'; import signals from '../signals'; import { JudgeTask } from '../task'; -import { compilerText, parseMemoryMB, parseTimeMS } from '../utils'; - -const failure = (status: number, message?: string) => ({ - status, - score: 0, - time: 0, - memory: 0, - message, -}); +import { parseMemoryMB, parseTimeMS } from '../utils'; const logger = new Logger('judge/run'); export const judge = async (ctx: JudgeTask) => { ctx.stat.judge = new Date(); ctx.next({ status: STATUS.STATUS_COMPILING }); - let execute: Execute; - try { - execute = await ctx.compile( - ctx.lang, ctx.code, - Object.fromEntries( - (ctx.config.user_extra_files || []).map((i) => [i.split('/').pop(), { src: i }]), - ), - ); - } catch (e) { - if (e instanceof CompileError) { - ctx.next({ - status: STATUS.STATUS_COMPILE_ERROR, - case: failure(STATUS.STATUS_COMPILE_ERROR, compilerText(e.stdout, e.stderr)), - }); - ctx.end(failure(STATUS.STATUS_COMPILE_ERROR)); - } else { - ctx.next({ - status: STATUS.STATUS_SYSTEM_ERROR, - case: failure(STATUS.STATUS_SYSTEM_ERROR, `${e.message}\n${JSON.stringify(e.params)}`), - }); - ctx.end(failure(STATUS.STATUS_SYSTEM_ERROR)); - } - return; - } + const execute = await ctx.compile(ctx.lang, ctx.code); ctx.next({ status: STATUS.STATUS_JUDGING, progress: 0 }); const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang); const res = await runQueued( @@ -76,6 +43,9 @@ export const judge = async (ctx: JudgeTask) => { message.push(res.stdout, res.stderr); ctx.next({ status, + time: Math.floor(time * 1000000) / 1000000, + memory, + score: status === STATUS.STATUS_ACCEPTED ? 100 : 0, case: { subtaskId: 0, status, @@ -86,39 +56,9 @@ export const judge = async (ctx: JudgeTask) => { }, }); if ([STATUS.STATUS_WRONG_ANSWER, STATUS.STATUS_RUNTIME_ERROR].includes(status)) { - const langConfig = ctx.session.getLang(ctx.lang); - if (langConfig.analysis) { - try { - const r = await runQueued(langConfig.analysis, { - copyIn: { - ...execute.copyIn, - input: { content: ctx.input }, - [langConfig.code_file || 'foo']: ctx.code, - compile: { content: langConfig.compile || '' }, - execute: { content: langConfig.execute || '' }, - }, - env: { - ...ctx.env, - HYDRO_PRETEST: 'true', - }, - time: 5000, - memory: 256, - }); - const out = r.stdout.toString(); - if (out.length) ctx.next({ compilerText: out.substring(0, 1024) }); - if (process.env.DEV) console.log(r); - } catch (e) { - logger.info('Failed to run analysis'); - logger.error(e); - } - } + await ctx.runAnalysis(execute, { content: ctx.input }); } ctx.stat.done = new Date(); if (process.env.DEV) ctx.next({ message: JSON.stringify(ctx.stat) }); - ctx.end({ - status, - score: status === STATUS.STATUS_ACCEPTED ? 100 : 0, - time: Math.floor(time * 1000000) / 1000000, - memory, - }); + ctx.end({ status }); }; diff --git a/packages/hydrojudge/src/task.ts b/packages/hydrojudge/src/task.ts index fb7fe92e..1e6dfa49 100644 --- a/packages/hydrojudge/src/task.ts +++ b/packages/hydrojudge/src/task.ts @@ -10,10 +10,10 @@ import checkers from './checkers'; import compile, { compileWithTestlib } from './compile'; import { getConfig } from './config'; import { CompileError, FormatError } from './error'; -import { NextFunction, ParsedConfig } from './interface'; +import { Execute, NextFunction, ParsedConfig } from './interface'; import judge from './judge'; import { Logger } from './log'; -import { CopyIn, CopyInFile } from './sandbox'; +import { CopyIn, CopyInFile, runQueued } from './sandbox'; import { compilerText, md5 } from './utils'; interface Session { @@ -156,4 +156,29 @@ export class JudgeTask { this.clean.push(result.clean); return result; } + + async runAnalysis(execute: Execute, input: CopyInFile) { + const langConfig = this.session.getLang(this.lang); + if (!langConfig.analysis) return; + try { + const r = await runQueued(langConfig.analysis, { + copyIn: { + ...execute.copyIn, + input, + [langConfig.code_file || 'foo']: this.code, + compile: { content: langConfig.compile || '' }, + execute: { content: langConfig.execute || '' }, + }, + env: this.env, + time: 5000, + memory: 256, + }); + const out = r.stdout.toString(); + if (out.length) this.next({ compilerText: out.substring(0, 1024) }); + if (process.env.DEV) console.log(r); + } catch (e) { + logger.info('Failed to run analysis'); + logger.error(e); + } + } }