mirror of
https://github.com/massbug/judge4c.git
synced 2025-05-18 07:16:34 +00:00
refactor(config/judge.ts, types/judge.ts): split judge configuration and types
This commit is contained in:
parent
808dd96a50
commit
a33033b48d
@ -3,7 +3,9 @@
|
||||
import tar from "tar-stream";
|
||||
import Docker from "dockerode";
|
||||
import { Readable, Writable } from "stream";
|
||||
import { ExitCode, JudgeResult, LanguageConfigs } from "@/config/judge";
|
||||
import { JudgeConfig } from "@/config/judge";
|
||||
import { EditorLanguage } from "@/types/editor-language";
|
||||
import { ExitCode, JudgeResultMetadata } from "@/types/judge";
|
||||
|
||||
// Docker client initialization
|
||||
const docker = new Docker({ socketPath: "/var/run/docker.sock" });
|
||||
@ -41,10 +43,11 @@ function createTarStream(file: string, value: string) {
|
||||
}
|
||||
|
||||
export async function judge(
|
||||
language: string,
|
||||
language: EditorLanguage,
|
||||
value: string
|
||||
): Promise<JudgeResult> {
|
||||
const { fileName, fileExtension, image, tag, workingDir, memoryLimit, timeLimit, compileOutputLimit, runOutputLimit } = LanguageConfigs[language];
|
||||
): Promise<JudgeResultMetadata> {
|
||||
const { fileName, fileExtension } = JudgeConfig[language].editorLanguageMetadata;
|
||||
const { image, tag, workingDir, memoryLimit, timeLimit, compileOutputLimit, runOutputLimit } = JudgeConfig[language].dockerMetadata;
|
||||
const file = `${fileName}.${fileExtension}`;
|
||||
let container: Docker.Container | undefined;
|
||||
|
||||
@ -70,14 +73,14 @@ export async function judge(
|
||||
}
|
||||
}
|
||||
|
||||
async function compile(container: Docker.Container, file: string, fileName: string, maxOutput: number = 1 * 1024 * 1024): Promise<JudgeResult> {
|
||||
async function compile(container: Docker.Container, file: string, fileName: string, maxOutput: number = 1 * 1024 * 1024): Promise<JudgeResultMetadata> {
|
||||
const compileExec = await container.exec({
|
||||
Cmd: ["gcc", "-O2", file, "-o", fileName],
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
});
|
||||
|
||||
return new Promise<JudgeResult>((resolve, reject) => {
|
||||
return new Promise<JudgeResultMetadata>((resolve, reject) => {
|
||||
compileExec.start({}, (error, stream) => {
|
||||
if (error || !stream) {
|
||||
return reject({ output: "System Error", exitCode: ExitCode.SE });
|
||||
@ -126,7 +129,7 @@ async function compile(container: Docker.Container, file: string, fileName: stri
|
||||
const stderr = stderrChunks.join("");
|
||||
const exitCode = (await compileExec.inspect()).ExitCode;
|
||||
|
||||
let result: JudgeResult;
|
||||
let result: JudgeResultMetadata;
|
||||
|
||||
if (exitCode !== 0 || stderr) {
|
||||
result = { output: stderr || "Compilation Error", exitCode: ExitCode.CE };
|
||||
@ -145,14 +148,14 @@ async function compile(container: Docker.Container, file: string, fileName: stri
|
||||
}
|
||||
|
||||
// Run code and implement timeout
|
||||
async function run(container: Docker.Container, fileName: string, timeLimit?: number, maxOutput: number = 1 * 1024 * 1024): Promise<JudgeResult> {
|
||||
async function run(container: Docker.Container, fileName: string, timeLimit?: number, maxOutput: number = 1 * 1024 * 1024): Promise<JudgeResultMetadata> {
|
||||
const runExec = await container.exec({
|
||||
Cmd: [`./${fileName}`],
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
});
|
||||
|
||||
return new Promise<JudgeResult>((resolve, reject) => {
|
||||
return new Promise<JudgeResultMetadata>((resolve, reject) => {
|
||||
const stdoutChunks: string[] = [];
|
||||
let stdoutLength = 0;
|
||||
const stdoutStream = new Writable({
|
||||
@ -211,7 +214,7 @@ async function run(container: Docker.Container, fileName: string, timeLimit?: nu
|
||||
const stderr = stderrChunks.join("");
|
||||
const exitCode = (await runExec.inspect()).ExitCode;
|
||||
|
||||
let result: JudgeResult;
|
||||
let result: JudgeResultMetadata;
|
||||
|
||||
// Exit code 0 means successful execution
|
||||
if (exitCode === 0) {
|
||||
|
@ -1,42 +1,9 @@
|
||||
// Result type definitions
|
||||
export enum ExitCode {
|
||||
SE = 0, // System Error
|
||||
CS = 1, // Compilation Success
|
||||
CE = 2, // Compilation Error
|
||||
TLE = 3, // Time Limit Exceeded
|
||||
MLE = 4, // Memory Limit Exceeded
|
||||
RE = 5, // Runtime Error
|
||||
AC = 6, // Accepted
|
||||
WA = 7, // Wrong Answer
|
||||
}
|
||||
import { EditorLanguage } from "@/types/editor-language";
|
||||
import { EditorLanguageConfig } from "./editor-language";
|
||||
import { DockerMetadata, JudgeMetadata } from "@/types/judge";
|
||||
|
||||
export type JudgeResult = {
|
||||
output: string;
|
||||
exitCode: ExitCode;
|
||||
executionTime?: number;
|
||||
memoryUsage?: number;
|
||||
};
|
||||
|
||||
export interface LanguageConfig {
|
||||
id: string;
|
||||
label: string;
|
||||
fileName: string;
|
||||
fileExtension: string;
|
||||
image: string;
|
||||
tag: string;
|
||||
workingDir: string;
|
||||
timeLimit: number;
|
||||
memoryLimit: number;
|
||||
compileOutputLimit: number;
|
||||
runOutputLimit: number;
|
||||
}
|
||||
|
||||
export const LanguageConfigs: Record<string, LanguageConfig> = {
|
||||
c: {
|
||||
id: "c",
|
||||
label: "C",
|
||||
fileName: "main",
|
||||
fileExtension: "c",
|
||||
export const DockerConfig: Record<EditorLanguage, DockerMetadata> = {
|
||||
[EditorLanguage.C]: {
|
||||
image: "gcc",
|
||||
tag: "latest",
|
||||
workingDir: "/src",
|
||||
@ -45,11 +12,7 @@ export const LanguageConfigs: Record<string, LanguageConfig> = {
|
||||
compileOutputLimit: 1 * 1024 * 1024,
|
||||
runOutputLimit: 1 * 1024 * 1024,
|
||||
},
|
||||
cpp: {
|
||||
id: "cpp",
|
||||
label: "C++",
|
||||
fileName: "main",
|
||||
fileExtension: "cpp",
|
||||
[EditorLanguage.CPP]: {
|
||||
image: "gcc",
|
||||
tag: "latest",
|
||||
workingDir: "/src",
|
||||
@ -57,5 +20,16 @@ export const LanguageConfigs: Record<string, LanguageConfig> = {
|
||||
memoryLimit: 128,
|
||||
compileOutputLimit: 1 * 1024 * 1024,
|
||||
runOutputLimit: 1 * 1024 * 1024,
|
||||
}
|
||||
}
|
||||
|
||||
export const JudgeConfig: Record<EditorLanguage, JudgeMetadata> = {
|
||||
[EditorLanguage.C]: {
|
||||
editorLanguageMetadata: EditorLanguageConfig[EditorLanguage.C],
|
||||
dockerMetadata: DockerConfig[EditorLanguage.C],
|
||||
},
|
||||
[EditorLanguage.CPP]: {
|
||||
editorLanguageMetadata: EditorLanguageConfig[EditorLanguage.CPP],
|
||||
dockerMetadata: DockerConfig[EditorLanguage.CPP],
|
||||
},
|
||||
};
|
||||
|
35
src/types/judge.ts
Normal file
35
src/types/judge.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { EditorLanguageMetadata } from "./editor-language";
|
||||
|
||||
// Result type definitions
|
||||
export enum ExitCode {
|
||||
SE = 0, // System Error
|
||||
CS = 1, // Compilation Success
|
||||
CE = 2, // Compilation Error
|
||||
TLE = 3, // Time Limit Exceeded
|
||||
MLE = 4, // Memory Limit Exceeded
|
||||
RE = 5, // Runtime Error
|
||||
AC = 6, // Accepted
|
||||
WA = 7, // Wrong Answer
|
||||
}
|
||||
|
||||
export type JudgeResultMetadata = {
|
||||
output: string;
|
||||
exitCode: ExitCode;
|
||||
executionTime?: number;
|
||||
memoryUsage?: number;
|
||||
};
|
||||
|
||||
export type JudgeMetadata = {
|
||||
editorLanguageMetadata: EditorLanguageMetadata;
|
||||
dockerMetadata: DockerMetadata;
|
||||
};
|
||||
|
||||
export type DockerMetadata = {
|
||||
image: string;
|
||||
tag: string;
|
||||
workingDir: string;
|
||||
timeLimit: number;
|
||||
memoryLimit: number;
|
||||
compileOutputLimit: number;
|
||||
runOutputLimit: number;
|
||||
}
|
Loading…
Reference in New Issue
Block a user