原来试运行走另一台 Judge0:C 是 GCC 9、编译参数也不一样,Python 的语法错误回来的是运行错误, 没有题目的时间内存限制和代码模板,例子上的结果常和提交对不上。现在走本站判题机 (POST /trial-runs),同一套编译命令、这道题的限制和模板,对不对也由判题机比。 - 不落库、不算提交、不进判题队列:api 进程里自己排队,全站同时 TRIAL_CONCURRENCY 批 (服务器 2、机房 4),每人最多两批,排满或等超过 30 秒就请学生过一会儿再点 - 死循环不停打印时判题机回包会很大,超过 16MB 就掐断,告诉学生输出太多、停不下来 - Python 语法错误用和提交一样的说明:第几行、中文标点标红、一键换成英文 - 运行时错误和提交用同一个解析,说清楚第几行、为什么(下标越界、int() 转换失败、段错误……); 比赛里照旧只给按结果码的那一句 - 语法没过、服务没跑成时,标题不再说「N 个例子没对上」 - 后台「生成测试点」一并迁过来,编译警告不会再写进 .out;Judge0 的地址和调用全部删掉 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8834536135
commit
eb32676de4
27 files changed
+691
-169
No files matched your search
@@ -1,7 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { TRIAL_ADMIN_MAX_CASES } from "@oj2/contract"
|
||||
import type { LANGUAGE, Testcase } from "utils/types"
|
||||
import { errorMessage } from "utils/api"
|
||||
import { SubmissionStatus } from "utils/constants"
|
||||
import { createZipBlob } from "utils/functions"
|
||||
import { createTestSubmission } from "utils/judge"
|
||||
import { isRunnableLanguage, trialRun } from "utils/judge"
|
||||
import { uploadTestcases } from "../../api"
|
||||
|
||||
interface FileEntry {
|
||||
@@ -146,25 +149,45 @@ async function run() {
|
||||
// 清空旧输出
|
||||
files.value = files.value.map((f) => ({ ...f, out: "", error: false }))
|
||||
|
||||
// 走本站判题机(和判题同一套编译命令),不带题号:题目可能还没存,按后端给管理员的默认限制跑。
|
||||
// 一次最多 TRIAL_ADMIN_MAX_CASES 组,多了分几批
|
||||
const language = selectedLanguage.value
|
||||
if (!isRunnableLanguage(language)) {
|
||||
message.error(`${language} 不能用来生成测试点`)
|
||||
return
|
||||
}
|
||||
isRunning.value = true
|
||||
await Promise.all(
|
||||
files.value.map(async (_, i) => {
|
||||
try {
|
||||
const result = await createTestSubmission(
|
||||
{ language: selectedLanguage.value, value: answer.code },
|
||||
files.value[i].in,
|
||||
)
|
||||
files.value[i] = {
|
||||
...files.value[i],
|
||||
out: result.output,
|
||||
error: result.status !== 3,
|
||||
try {
|
||||
for (let start = 0; start < files.value.length; start += TRIAL_ADMIN_MAX_CASES) {
|
||||
const batch = files.value.slice(start, start + TRIAL_ADMIN_MAX_CASES)
|
||||
const response = await trialRun({
|
||||
language,
|
||||
code: answer.code,
|
||||
cases: batch.map((f) => ({ input: f.in })),
|
||||
})
|
||||
batch.forEach((_, offset) => {
|
||||
const i = start + offset
|
||||
if (response.status === "compile-error") {
|
||||
files.value[i] = { ...files.value[i], out: response.message, error: true }
|
||||
} else if (response.status === "too-much-output") {
|
||||
files.value[i] = { ...files.value[i], out: "输出太多,判题机回包超过上限", error: true }
|
||||
} else {
|
||||
const run = response.cases[offset]!
|
||||
const ok = run.result === SubmissionStatus.accepted
|
||||
files.value[i] = {
|
||||
...files.value[i],
|
||||
out: ok ? run.output.trimEnd() : run.output,
|
||||
error: !ok,
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
files.value[i] = { ...files.value[i], out: "", error: true }
|
||||
}
|
||||
}),
|
||||
)
|
||||
isRunning.value = false
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
message.error(errorMessage(err, "运行失败"))
|
||||
files.value = files.value.map((f) => (f.out ? f : { ...f, error: true }))
|
||||
} finally {
|
||||
isRunning.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function upload() {
|
||||
|
||||
Reference in new issue
Block a user