core&judge: probe compiler versions

This commit is contained in:
undefined committed 2024-06-16 14:33:54 +08:00
1 parent 5803a1d94d
commit e62a7fe394
6 files changed
+94 -9

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
import { LangConfig } from '@hydrooj/utils/lib/lang';
import { runQueued } from './sandbox';
export async function compilerVersions(langs: Record<string, LangConfig>) {
const result = {};
for (const lang in langs) {
const version = langs[lang].version;
if (!version) continue;
// eslint-disable-next-line no-await-in-loop
const res = await runQueued(version, {
copyIn: {},
time: 10000,
memory: 256 * 1024 * 1024,
}, 5);
result[lang] = `${res.stdout}\n${res.stderr}`.trim();
}
return result;
}
+16 -2
View File
@@ -2,10 +2,13 @@
/* eslint-disable no-await-in-loop */
import path from 'path';
import { fs } from '@hydrooj/utils';
import * as sysinfo from '@hydrooj/utils/lib/sysinfo';
import {
JudgeHandler, JudgeResultBody, ObjectId, RecordModel, SettingModel,
StorageModel, SystemModel, TaskModel,
db, JudgeHandler, JudgeResultBody, ObjectId, RecordModel,
SettingModel, StorageModel, SystemModel, TaskModel,
} from 'hydrooj';
import { langs } from 'hydrooj/src/model/setting';
import { compilerVersions } from '../compiler';
import { getConfig } from '../config';
import { FormatError, SystemError } from '../error';
import { Context } from '../judge/interface';
@@ -82,6 +85,7 @@ export async function postInit(ctx) {
c.check.addChecker('Judge', (_ctx, log, warn, error) => versionCheck(warn, error));
});
await fs.ensureDir(getConfig('tmp_dir'));
const info = await sysinfo.get();
const handle = async (t) => {
const rdoc = await RecordModel.get(t.domainId, t.rid);
if (!rdoc) {
@@ -92,9 +96,19 @@ export async function postInit(ctx) {
};
const parallelism = Math.max(getConfig('parallelism'), 2);
const taskConsumer = TaskModel.consume({ type: 'judge' }, handle, true, parallelism);
function collectCompilerInfo() {
const coll = db.collection('status');
compilerVersions(langs).then((compilers) => coll.updateOne(
{ mid: info.mid, type: 'judge' },
{ $set: { compilers } },
{ upsert: true },
)).catch((e) => logger.error(e));
}
ctx.on('system/setting', () => {
taskConsumer.setConcurrency(Math.max(getConfig('parallelism'), 2));
collectCompilerInfo();
});
collectCompilerInfo();
TaskModel.consume({ type: 'judge', priority: { $gt: -50 } }, handle);
TaskModel.consume({ type: 'generate' }, handle);
}
+10 -3
View File
@@ -7,6 +7,7 @@ import { fs, pipeRequest } from '@hydrooj/utils';
import { LangConfig } from '@hydrooj/utils/lib/lang';
import * as sysinfo from '@hydrooj/utils/lib/sysinfo';
import type { JudgeResultBody } from 'hydrooj';
import { compilerVersions } from '../compiler';
import { getConfig } from '../config';
import { FormatError, SystemError } from '../error';
import { Session } from '../interface';
@@ -173,13 +174,19 @@ export default class Hydro implements Session {
const content = Object.keys(config).length
? JSON.stringify({ key: 'config', ...config })
: '{"key":"ping"}';
let compilers = {};
this.ws.on('message', (data) => {
if (data.toString() === 'ping') {
this.ws.send('pong');
return;
}
const request = JSON.parse(data.toString());
if (request.language) this.language = request.language;
if (request.language) {
this.language = request.language;
compilerVersions(this.language).then((res) => {
compilers = res;
});
}
if (request.task) queue.add(() => new JudgeTask(this, request.task).handle().catch((e) => log.error(e)));
});
this.ws.on('close', (data, reason) => {
@@ -196,10 +203,10 @@ export default class Hydro implements Session {
this.ws.send('{"key":"start"}');
if (!this.config.noStatus) {
const info = await sysinfo.get();
this.ws.send(JSON.stringify({ key: 'status', info }));
this.ws.send(JSON.stringify({ key: 'status', info: { ...info, compilers } }));
setInterval(async () => {
const [mid, inf] = await sysinfo.update();
this.ws.send(JSON.stringify({ key: 'status', info: { mid, ...inf } }));
this.ws.send(JSON.stringify({ key: 'status', info: { mid, ...inf, compilers } }));
}, 1200000);
}
resolve(null);