From bf66df77ab3803b23af35db2b2352263d36f0bf1 Mon Sep 17 00:00:00 2001 From: Shine Chang Date: Sun, 6 Oct 2024 19:37:38 -0700 Subject: [PATCH] (wip) dump --- .../src/services/submission.services.ts | 3 +- .../src/services/compile.services.ts | 50 ++++++++++++++++--- .../src/services/grading.services.ts | 7 +++ packages/judge-daemon/src/start.ts | 3 -- .../src/services/result.services.ts | 2 +- packages/types/src/types/compilation.types.ts | 6 +++ 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/packages/api-server/src/services/submission.services.ts b/packages/api-server/src/services/submission.services.ts index 586b603b..a926f417 100644 --- a/packages/api-server/src/services/submission.services.ts +++ b/packages/api-server/src/services/submission.services.ts @@ -5,7 +5,7 @@ import { SubmissionStatus, type Submission, type Problem -} from '@argoncs/types' +} from '@argoncs/types' /*=*/ import { rabbitMQ, judgerExchange, judgerTasksKey, submissionCollection, fetchDomainProblem, fetchContestProblem } from '@argoncs/common' import { languageConfigs } from '../../configs/language.configs.js' @@ -45,6 +45,7 @@ async function createSubmission ({ submission, userId, target }: { submission: N const task: CompilingTask = { submissionId, + problemId: problem.id, type: JudgerTaskType.Compiling, source: submission.source, language: submission.language, diff --git a/packages/judge-daemon/src/services/compile.services.ts b/packages/judge-daemon/src/services/compile.services.ts index 0fad2f36..27bb58ae 100644 --- a/packages/judge-daemon/src/services/compile.services.ts +++ b/packages/judge-daemon/src/services/compile.services.ts @@ -7,7 +7,8 @@ import { type CompilingTask, SandboxStatus, type CompileSucceeded, type CompileF import { minio } from '@argoncs/common' import { languageConfigs } from '../../configs/language.configs.js' -//= +/*=*/ + export async function compileSubmission ({ task, boxId }: { task: CompilingTask, boxId: number }): Promise { const workDir = `/var/local/lib/isolate/${boxId}/box` const config = languageConfigs[task.language] @@ -15,19 +16,20 @@ export async function compileSubmission ({ task, boxId }: { task: CompilingTask, const binaryPath = path.join(workDir, config.binaryFile) const logPath = path.join(workDir, 'log.txt') await fs.writeFile(srcPath, task.source) - let command = config.compileCommand - command = command.replaceAll('{src_path}', config.srcFile) - command = command.replaceAll('{binary_path}', config.binaryFile) + + const command = config.compileCommand + .replaceAll('{src_path}', config.srcFile) + .replaceAll('{binary_path}', config.binaryFile) console.log('command:', command); - console.log(workDir, config, srcPath, binaryPath, logPath); + console.log(workDir, config, srcPath, binaryPath); const result = await runInSandbox( { task: { constraints: task.constraints, command, - stderrPath: 'log.txt', + stderrPath: logPath, env: 'PATH=/bin:/usr/local/bin:/usr/bin' }, boxId @@ -47,3 +49,39 @@ export async function compileSubmission ({ task, boxId }: { task: CompilingTask, } } } + +export async function compileChecker ({ task, boxId }: { task: CompilingTask, boxId: number }): Promise { + + const workDir = `/var/local/lib/isolate/${boxId}/box` + const srcPath = path.join(workDir, 'checker.cpp') + const binaryPath = path.join(workDir, 'checker') + const logPath = path.join(workDir, 'checker-log.txt') + await fetchCheckerSource(srcPath); + + const command = '/usr/bin/g++ -o2 -w -fmax-errors=3 -std=c++17 checker.cpp -lm -o checker' + + console.log('command:', command); + console.log(workDir, srcPath, binaryPath); + + const result = await runInSandbox( + { + task: { + constraints: {}, + command, + stderrPath: logPath, + env: 'PATH=/bin:/usr/local/bin:/usr/bin' + }, + boxId + }) + + console.log('compiled') + if (result.status !== SandboxStatus.Succeeded) { + return { + status: CompilingStatus.Failed, + log: (await fs.readFile(logPath)).toString() + } + } + + await minio.fPutObject('checkers', task.problemId, binaryPath) + return { status: CompilingStatus.Succeeded } +} diff --git a/packages/judge-daemon/src/services/grading.services.ts b/packages/judge-daemon/src/services/grading.services.ts index 719d13c5..65be5e9c 100644 --- a/packages/judge-daemon/src/services/grading.services.ts +++ b/packages/judge-daemon/src/services/grading.services.ts @@ -10,6 +10,7 @@ import { } from './sandbox.services.js' import { fetchBinary, fetchTestcase } from './storage.services.js' +import {NotFoundError} from 'http-errors-enhanced' export async function gradeSubmission ({ task, boxId }: { task: GradingTask, boxId: number }): Promise { @@ -18,11 +19,16 @@ export async function gradeSubmission ({ task, boxId }: { task: GradingTask, box const binaryPath = path.join(workDir, config.binaryFile) const inputPath = path.join(workDir, 'in.txt') const answerPath = path.join(workDir, 'ans.txt') + const checkerPath = path.join(workDir, 'checker'); await fetchBinary({ objectName: task.submissionId, destPath: binaryPath }) await fetchTestcase({ objectName: task.testcase.input.objectName, versionId: task.testcase.input.versionId, destPath: inputPath }) await fetchTestcase({ objectName: task.testcase.output.objectName, versionId: task.testcase.output.versionId, destPath: answerPath }) await makeExecutable(path.join(workDir, config.binaryFile)) + await fetchChecker({ + objectName: task.checker.objectName, + versionId: task.checker.versionId, + destPath: checkerPath }) let command = config.executeCommand command = command.replaceAll('{binary_path}', config.binaryFile) @@ -38,6 +44,7 @@ export async function gradeSubmission ({ task, boxId }: { task: GradingTask, box }, boxId }) + //return new Promise((resolve, reject) => resolve({ message: '', status: GradingStatus.Accepted, memory: 1, time: 1, wallTime: 1})); if (sandboxResult.status === SandboxStatus.Succeeded) { diff --git a/packages/judge-daemon/src/start.ts b/packages/judge-daemon/src/start.ts index 77d414a0..5d1d1ac0 100644 --- a/packages/judge-daemon/src/start.ts +++ b/packages/judge-daemon/src/start.ts @@ -74,7 +74,6 @@ export async function startJudger (): Promise { submissionId: task.submissionId, testcaseIndex: task.testcaseIndex } - // send grade message } else if (task.type === JudgerTaskType.Compiling) { console.log('compiling') result = { @@ -82,8 +81,6 @@ export async function startJudger (): Promise { result: (await compileSubmission({ task, boxId })), submissionId: task.submissionId } - - // send grade message } else { throw Error('Invalid task type') } diff --git a/packages/result-handler/src/services/result.services.ts b/packages/result-handler/src/services/result.services.ts index d75e573c..ae1b849a 100644 --- a/packages/result-handler/src/services/result.services.ts +++ b/packages/result-handler/src/services/result.services.ts @@ -1,5 +1,5 @@ import { fetchContestProblem, fetchDomainProblem, fetchSubmission, judgerExchange, judgerTasksKey, rabbitMQ, ranklistRedis, recalculateTeamTotalScore, submissionCollection, teamScoreCollection } from '@argoncs/common' -import { type CompilingResult, CompilingStatus, type GradingResult, GradingStatus, type GradingTask, JudgerTaskType, type Problem, SubmissionStatus } from '@argoncs/types' +import { type CompilingResult, CompilingStatus, type GradingResult, GradingStatus, type GradingTask, JudgerTaskType, type Problem, SubmissionStatus } from '@argoncs/types' /*=*/ import { NotFoundError } from 'http-errors-enhanced' import path from 'path' diff --git a/packages/types/src/types/compilation.types.ts b/packages/types/src/types/compilation.types.ts index c3d582f7..9a06f2ce 100644 --- a/packages/types/src/types/compilation.types.ts +++ b/packages/types/src/types/compilation.types.ts @@ -50,3 +50,9 @@ export interface CompilingResultMessage { submissionId: string result: CompilingResult } + +export interface CheckerCompileTask { + type: JudgerTaskType.CheckerCompile, + source: string, + problemId: string, +}