mirror of
https://github.com/massbug/judge4c.git
synced 2025-05-18 07:16:34 +00:00
fix(judge): ensure container remains running and capture stderr separately
This commit is contained in:
parent
83deae7a02
commit
38038dc7b1
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import tar from "tar-stream";
|
import tar from "tar-stream";
|
||||||
import Docker from "dockerode";
|
import Docker from "dockerode";
|
||||||
import { Readable } from "stream";
|
import { Readable, Writable } from "stream";
|
||||||
import { LanguageConfigs } from "@/config/judge";
|
import { LanguageConfigs } from "@/config/judge";
|
||||||
|
|
||||||
const docker = new Docker({ socketPath: "/var/run/docker.sock" });
|
const docker = new Docker({ socketPath: "/var/run/docker.sock" });
|
||||||
@ -20,7 +20,7 @@ async function prepareEnvironment(image: string, tag: string) {
|
|||||||
async function createContainer(image: string, tag: string, workingDir: string) {
|
async function createContainer(image: string, tag: string, workingDir: string) {
|
||||||
const container = await docker.createContainer({
|
const container = await docker.createContainer({
|
||||||
Image: `${image}:${tag}`,
|
Image: `${image}:${tag}`,
|
||||||
Tty: true,
|
Cmd: ["tail", "-f", "/dev/null"],
|
||||||
WorkingDir: workingDir,
|
WorkingDir: workingDir,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -51,9 +51,36 @@ async function compileCode(container: Docker.Container, filePath: string, fileNa
|
|||||||
return reject(new Error("Stream is undefined"));
|
return reject(new Error("Stream is undefined"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = "";
|
let stdoutChunks: string[] = [];
|
||||||
stream.on("data", (chunk) => (data += chunk.toString()));
|
let stderrChunks: string[] = [];
|
||||||
stream.on("end", () => resolve(data));
|
|
||||||
|
const stdoutStream = new Writable({
|
||||||
|
write(chunk, encoding, callback) {
|
||||||
|
stdoutChunks.push(chunk.toString());
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const stderrStream = new Writable({
|
||||||
|
write(chunk, encoding, callback) {
|
||||||
|
stderrChunks.push(chunk.toString());
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
docker.modem.demuxStream(stream, stdoutStream, stderrStream);
|
||||||
|
|
||||||
|
stream.on("end", () => {
|
||||||
|
const stdout = stdoutChunks.join("");
|
||||||
|
const stderr = stderrChunks.join("");
|
||||||
|
|
||||||
|
if (stderr) {
|
||||||
|
resolve(stdout + stderr);
|
||||||
|
} else {
|
||||||
|
resolve(stdout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
stream.on("error", (error) => reject(error));
|
stream.on("error", (error) => reject(error));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -75,9 +102,35 @@ async function runCode(container: Docker.Container, fileName: string) {
|
|||||||
return reject(new Error("Stream is undefined"));
|
return reject(new Error("Stream is undefined"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = "";
|
let stdoutChunks: string[] = [];
|
||||||
stream.on("data", (chunk) => (data += chunk.toString()));
|
let stderrChunks: string[] = [];
|
||||||
stream.on("end", () => resolve(data));
|
|
||||||
|
const stdoutStream = new Writable({
|
||||||
|
write(chunk, encoding, callback) {
|
||||||
|
stdoutChunks.push(chunk.toString());
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const stderrStream = new Writable({
|
||||||
|
write(chunk, encoding, callback) {
|
||||||
|
stderrChunks.push(chunk.toString());
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
docker.modem.demuxStream(stream, stdoutStream, stderrStream);
|
||||||
|
|
||||||
|
stream.on("end", () => {
|
||||||
|
const stdout = stdoutChunks.join("");
|
||||||
|
const stderr = stderrChunks.join("");
|
||||||
|
if (stderr) {
|
||||||
|
resolve(stdout + stderr);
|
||||||
|
} else {
|
||||||
|
resolve(stdout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
stream.on("error", (error) => reject(error));
|
stream.on("error", (error) => reject(error));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -116,7 +169,7 @@ export async function judge(language: string, value: string) {
|
|||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
if (container) {
|
if (container) {
|
||||||
cleanupContainer(container).catch(() => {});
|
cleanupContainer(container).catch(() => { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user