From bc42ade705067eff5d816a3c95fe42eb104aa97c Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 2 Nov 2026 21:57:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=88=A4=E9=A2=98):=20SQL=20=E9=A2=98?= =?UTF-8?q?=E5=88=A4=E9=A2=98=E4=B9=9F=E6=8E=92=E9=98=9F=E5=8D=A0=E5=90=8D?= =?UTF-8?q?=E9=A2=9D=EF=BC=8C=E5=92=8C=E5=88=AB=E7=9A=84=E5=88=A4=E9=A2=98?= =?UTF-8?q?=E4=B8=80=E8=B5=B7=E6=8A=A2=E9=82=A3=E4=B8=A4=E4=B8=AA=E6=A0=B8?= =?UTF-8?q?=E6=97=B6=E4=B8=8D=E5=86=8D=E8=A2=AB=E8=AF=AF=E5=88=A4=E8=B6=85?= =?UTF-8?q?=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SQL 子进程在 worker 里跑,原来不经判题名额(judge/slots.ts):两道 SQL、两道沙箱判题、 再加流程图试运行可以同时压在服务器两个核上,SQL 的时限按墙钟算,挤的时候本来不超时的 语句会被判成超时。现在和沙箱判题占同一个池,一个名额管整份提交,租约按每个测试点 最长可能占的时间算。 Co-Authored-By: Claude Opus 5.5 --- apps/api/src/judge/run.ts | 21 ++++++++++++++++++++- apps/api/src/judge/sql/index.ts | 8 ++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/apps/api/src/judge/run.ts b/apps/api/src/judge/run.ts index 0eadb1e..969b38d 100644 --- a/apps/api/src/judge/run.ts +++ b/apps/api/src/judge/run.ts @@ -14,7 +14,7 @@ import type { JudgeJobData } from './job' import { isAccepted, JudgeStatus, type JudgeStatusValue } from './status' import { parseProblemTemplate, shiftCompileLines } from './template' import { withJudgeSlot } from './slots' -import { runSqlCase } from './sql' +import { runSqlCase, sqlCaseBudgetMs } from './sql' import { nativeRuntimeError, parsePythonTraceback, type RuntimeErrorInfo } from './runtime-diagnosis' import { compileError, judge, JudgeUnreachableError, type JudgeCase, type JudgeResponse } from './sandbox' import { readInfo } from '../services/test-case' @@ -625,6 +625,25 @@ async function judgeSqlSubmission(problem: typeof schema.problem.$inferSelect, s const keys = Object.keys(info.test_cases ?? {}).sort((a, b) => Number(a) - Number(b)) if (keys.length === 0) throw new Error('题目没有任何测试点') + /** + * 和沙箱判题占同一个池的名额(judge/slots.ts):SQL 子进程在 worker 里跑,同样吃服务器 + * 那两个核,原来不排队 —— 两道 SQL 加两道沙箱判题、再加流程图试运行一起压上去, + * 按墙钟算的 SQL 时限就会把本来不超时的语句判成超时。一个名额管整份提交,和沙箱那边一样。 + * 租约按每个测试点最长可能占的时间算,再加 30 秒 + */ + const holdMs = keys.length * sqlCaseBudgetMs(problem.timeLimit) + 30_000 + return withJudgeSlot('judge', { holdMs }, () => judgeSqlCases(problem, keys, info, refSql, studentSql, mode, sqlConfig)) +} + +async function judgeSqlCases( + problem: typeof schema.problem.$inferSelect, + keys: string[], + info: NonNullable>>, + refSql: string, + studentSql: string, + mode: 'query' | 'modify', + sqlConfig: Record, +): Promise { const cases: JudgeCase[] = [] for (const [index, key] of keys.entries()) { const inputName = info.test_cases![key]!.input_name diff --git a/apps/api/src/judge/sql/index.ts b/apps/api/src/judge/sql/index.ts index 4597131..cce3287 100644 --- a/apps/api/src/judge/sql/index.ts +++ b/apps/api/src/judge/sql/index.ts @@ -172,6 +172,14 @@ async function runJob(job: SqlJob, budget: JobBudget): Promise) { return runJob(job, { trustedMs: trustedBudgetMs(job.timeLimitMs),