[sandbox] Update deps

This commit is contained in:
orosmatthew 2023-12-19 16:59:34 -05:00
parent a19950a094
commit 27d2132bfa
4 changed files with 74 additions and 56 deletions

View File

@ -10,16 +10,16 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"fs-extra": "^11.1.1", "fs-extra": "^11.2.0",
"simple-git": "^3.20.0", "simple-git": "^3.21.0",
"url-join": "^5.0.0", "url-join": "^5.0.0",
"zod": "^3.22.4" "zod": "^3.22.4"
}, },
"devDependencies": { "devDependencies": {
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/node": "^20.9.2", "@types/node": "^20.10.5",
"prettier": "^3.1.0", "prettier": "^3.1.1",
"typescript": "^5.2.2" "typescript": "^5.3.3"
} }
}, },
"node_modules/@kwsites/file-exists": { "node_modules/@kwsites/file-exists": {
@ -55,9 +55,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.9.2", "version": "20.10.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz",
"integrity": "sha512-WHZXKFCEyIUJzAwh3NyyTHYSR35SevJ6mZ1nWwJafKtiQbqRTIKSRcw3Ma3acqgsent3RRDqeVwpHntMk+9irg==", "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~5.26.4"
@ -91,9 +91,9 @@
} }
}, },
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "11.1.1", "version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
"integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
"dependencies": { "dependencies": {
"graceful-fs": "^4.2.0", "graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1", "jsonfile": "^6.0.1",
@ -125,9 +125,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "3.1.0", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
"integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin/prettier.cjs" "prettier": "bin/prettier.cjs"
@ -140,9 +140,9 @@
} }
}, },
"node_modules/simple-git": { "node_modules/simple-git": {
"version": "3.20.0", "version": "3.21.0",
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.20.0.tgz", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.21.0.tgz",
"integrity": "sha512-ozK8tl2hvLts8ijTs18iFruE+RoqmC/mqZhjs/+V7gS5W68JpJ3+FCTmLVqmR59MaUQ52MfGQuWsIqfsTbbJ0Q==", "integrity": "sha512-oTzw9248AF5bDTMk9MrxsRzEzivMlY+DWH0yWS4VYpMhNLhDWnN06pCtaUyPnqv/FpsdeNmRqmZugMABHRPdDA==",
"dependencies": { "dependencies": {
"@kwsites/file-exists": "^1.1.1", "@kwsites/file-exists": "^1.1.1",
"@kwsites/promise-deferred": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1",
@ -154,9 +154,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.2.2", "version": "5.3.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",

View File

@ -13,14 +13,14 @@
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/node": "^20.9.2", "@types/node": "^20.10.5",
"prettier": "^3.1.0", "prettier": "^3.1.1",
"typescript": "^5.2.2" "typescript": "^5.3.3"
}, },
"dependencies": { "dependencies": {
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"fs-extra": "^11.1.1", "fs-extra": "^11.2.0",
"simple-git": "^3.20.0", "simple-git": "^3.21.0",
"url-join": "^5.0.0", "url-join": "^5.0.0",
"zod": "^3.22.4" "zod": "^3.22.4"
} }

View File

@ -9,7 +9,7 @@ import { runJava } from './run/java.js';
export const timeoutSeconds = 30; export const timeoutSeconds = 30;
const RunResultKind = z.enum(["CompileFailed", "TimeLimitExceeded", "Completed", "SandboxError"]); const RunResultKind = z.enum(['CompileFailed', 'TimeLimitExceeded', 'Completed', 'SandboxError']);
export type RunResultKind = z.infer<typeof RunResultKind>; export type RunResultKind = z.infer<typeof RunResultKind>;
const RunResult = z const RunResult = z
@ -63,7 +63,9 @@ enum SubmissionProcessingResult {
async function fetchQueuedSubmission(): Promise<SubmissionGetData | undefined> { async function fetchQueuedSubmission(): Promise<SubmissionGetData | undefined> {
const res = await fetch(submissionApiUrl, { method: 'GET' }); const res = await fetch(submissionApiUrl, { method: 'GET' });
if (res.status !== 200) { if (res.status !== 200) {
console.error(`Failed to fetch from ${submissionApiUrl} with status: ${res.status} ${res.statusText}`); console.error(
`Failed to fetch from ${submissionApiUrl} with status: ${res.status} ${res.statusText}`
);
return undefined; return undefined;
} }
@ -95,10 +97,7 @@ async function cloneAndRun(submissionData: SubmissionGetData) {
console.log(`- CLONE: from ${teamRepoUrl}`); console.log(`- CLONE: from ${teamRepoUrl}`);
const git: SimpleGit = simpleGit({ baseDir: repoDir }); const git: SimpleGit = simpleGit({ baseDir: repoDir });
await git.clone( await git.clone(teamRepoUrl, '.');
teamRepoUrl,
'.'
);
await git.checkout(submissionData.submission.commitHash); await git.checkout(submissionData.submission.commitHash);
const problemName = submissionData.submission.problem.pascalName; const problemName = submissionData.submission.problem.pascalName;
let runResult: RunResult; let runResult: RunResult;
@ -114,19 +113,23 @@ async function cloneAndRun(submissionData: SubmissionGetData) {
} catch (error) { } catch (error) {
runResult = { runResult = {
kind: 'SandboxError', kind: 'SandboxError',
resultKindReason: `An unexpected error occurred: ${EOL} ${error}`}; resultKindReason: `An unexpected error occurred: ${EOL} ${error}`
};
} }
printRunResult(runResult); printRunResult(runResult);
const postBodyObject: SubmissionPostData = { submissionId: submissionData.submission.id, result: runResult }; const postBodyObject: SubmissionPostData = {
submissionId: submissionData.submission.id,
result: runResult
};
const res = await fetch(urlJoin(adminUrl, 'api/submission'), { const res = await fetch(urlJoin(adminUrl, 'api/submission'), {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postBodyObject) body: JSON.stringify(postBodyObject)
}); });
if (res.status !== 200) { if (res.status !== 200) {
console.error('- POST: Failed with error code: ' + res.status + " " + res.statusText); console.error('- POST: Failed with error code: ' + res.status + ' ' + res.statusText);
return; return;
} }
@ -144,11 +147,11 @@ function printRunResult(runResult: RunResult) {
function getRunResultDisplayText() { function getRunResultDisplayText() {
if (runResult.kind == 'SandboxError') { if (runResult.kind == 'SandboxError') {
return "Sandbox error: " + runResult.resultKindReason; return 'Sandbox error: ' + runResult.resultKindReason;
} }
if (runResult.kind == 'CompileFailed') { if (runResult.kind == 'CompileFailed') {
return "Failed to compile"; return 'Failed to compile';
} }
if (runResult.kind == 'TimeLimitExceeded') { if (runResult.kind == 'TimeLimitExceeded') {
@ -219,10 +222,12 @@ function printSubmissionHeader(submissionData: SubmissionGetData) {
} }
console.log(`--- Submission ${submission.id} ---`); console.log(`--- Submission ${submission.id} ---`);
console.log(`- INFO: Contest ${submission.contestId} '${submission.contestName}', ` + console.log(
`Team ${submission.teamId} '${submission.teamName}', ` + `- INFO: Contest ${submission.contestId} '${submission.contestName}', ` +
`Problem ${submission.problem.id} '${submission.problem.pascalName}', ` + `Team ${submission.teamId} '${submission.teamName}', ` +
`SHA '${submission.commitHash}'`); `Problem ${submission.problem.id} '${submission.problem.pascalName}', ` +
`SHA '${submission.commitHash}'`
);
} }
function printSubmissionFooter(submissionData: SubmissionGetData) { function printSubmissionFooter(submissionData: SubmissionGetData) {
@ -235,7 +240,7 @@ function printSubmissionFooter(submissionData: SubmissionGetData) {
} }
async function run() { async function run() {
console.log("Sandbox started. Periodically checking for submissions."); console.log('Sandbox started. Periodically checking for submissions.');
let iterationsSinceProcessedSubmission = 0; let iterationsSinceProcessedSubmission = 0;
let anySubmissionsProcessed = false; let anySubmissionsProcessed = false;
@ -248,8 +253,14 @@ async function run() {
case SubmissionProcessingResult.NoSubmissions: case SubmissionProcessingResult.NoSubmissions:
if (iterationsSinceProcessedSubmission > 0 && iterationsSinceProcessedSubmission % 6 == 0) { if (iterationsSinceProcessedSubmission > 0 && iterationsSinceProcessedSubmission % 6 == 0) {
const numMinutes = iterationsSinceProcessedSubmission / 6; const numMinutes = iterationsSinceProcessedSubmission / 6;
console.log(`${numMinutes} minute${(numMinutes > 1 ? 's' : '')} since ` + console.log(
`${(anySubmissionsProcessed ? `last submission processed` : `sandbox startup with no submissions`)}`); `${numMinutes} minute${numMinutes > 1 ? 's' : ''} since ` +
`${
anySubmissionsProcessed
? `last submission processed`
: `sandbox startup with no submissions`
}`
);
} }
await new Promise((resolve) => setTimeout(resolve, 10000)); await new Promise((resolve) => setTimeout(resolve, 10000));

View File

@ -20,10 +20,10 @@ export async function runJava(
try { try {
await execPromise(compileCommand); await execPromise(compileCommand);
} catch(e) { } catch (e) {
const buildErrorText = e?.toString() ?? "Unknown build errors."; const buildErrorText = e?.toString() ?? 'Unknown build errors.';
console.log("Build errors: " + buildErrorText); console.log('Build errors: ' + buildErrorText);
return {kind: 'CompileFailed', resultKindReason: buildErrorText}; return { kind: 'CompileFailed', resultKindReason: buildErrorText };
} }
console.log(`- RUN: ${mainClass}`); console.log(`- RUN: ${mainClass}`);
@ -55,12 +55,19 @@ export async function runJava(
if (completedNormally) { if (completedNormally) {
clearTimeout(timeoutHandle); clearTimeout(timeoutHandle);
resolve({kind: 'Completed', output: outputBuffer, resolve({
exitCode: child.exitCode!, runtimeMilliseconds}); kind: 'Completed',
} output: outputBuffer,
else { exitCode: child.exitCode!,
runtimeMilliseconds
});
} else {
console.log(`Process terminated, total sandbox time: ${runtimeMilliseconds}ms`); console.log(`Process terminated, total sandbox time: ${runtimeMilliseconds}ms`);
resolve({kind: 'TimeLimitExceeded', output: outputBuffer, resultKindReason: `Timeout after ${timeoutSeconds} seconds`}); resolve({
kind: 'TimeLimitExceeded',
output: outputBuffer,
resultKindReason: `Timeout after ${timeoutSeconds} seconds`
});
} }
}); });