Skip to content

Commit 8719be1

Browse files
committed
Refactor code to allow splitting the creation of judgetasks and queuetasks.
Progress towards #2019 No functional changes intended.
1 parent ac60eca commit 8719be1

File tree

1 file changed

+116
-102
lines changed

1 file changed

+116
-102
lines changed

webapp/src/Service/DOMJudgeService.php

Lines changed: 116 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,111 +1169,11 @@ public function maybeCreateJudgeTasks(Judging $judging, int $priority = JudgeTas
11691169
if ($submission->isImportError()) {
11701170
return;
11711171
}
1172-
1173-
$evalOnDemand = false;
1174-
// We have 2 cases, the problem picks the global value or the value is set.
1175-
if ($problem->determineOnDemand($this->config->get('lazy_eval_results'))) {
1176-
$evalOnDemand = true;
1177-
1178-
// Special case, we're shadow and someone submits on our side in that case
1179-
// we're not super lazy.
1180-
if ($this->config->get('data_source') === DOMJudgeService::DATA_SOURCE_CONFIGURATION_AND_LIVE_EXTERNAL
1181-
&& $submission->getExternalid() === null) {
1182-
$evalOnDemand = false;
1183-
}
1184-
if ($manualRequest) {
1185-
// When explicitly requested, judge the submission.
1186-
$evalOnDemand = false;
1187-
}
1188-
}
1189-
if (!$problem->getAllowJudge() || !$language->getAllowJudge() || $evalOnDemand) {
1172+
if (!$this->allowJudge($problem, $submission, $language, $manualRequest)) {
11901173
return;
11911174
}
11921175

1193-
// We use a mass insert query, since that is way faster than doing a separate insert for each testcase.
1194-
// We first insert judgetasks, then select their ID's and finally insert the judging runs.
1195-
1196-
// Step 1: Create the template for the judgetasks.
1197-
$compileExecutable = $submission->getLanguage()->getCompileExecutable()->getImmutableExecutable();
1198-
$judgetaskInsertParams = [
1199-
':type' => JudgeTaskType::JUDGING_RUN,
1200-
':submitid' => $submission->getSubmitid(),
1201-
':priority' => $priority,
1202-
':jobid' => $judging->getJudgingid(),
1203-
':uuid' => $judging->getUuid(),
1204-
':compile_script_id' => $compileExecutable->getImmutableExecId(),
1205-
':compare_script_id' => $this->getImmutableCompareExecutable($problem)->getImmutableExecId(),
1206-
':run_script_id' => $this->getImmutableRunExecutable($problem)->getImmutableExecId(),
1207-
':compile_config' => $this->getCompileConfig($submission),
1208-
':run_config' => $this->getRunConfig($problem, $submission),
1209-
':compare_config' => $this->getCompareConfig($problem),
1210-
];
1211-
1212-
$judgetaskDefaultParamNames = array_keys($judgetaskInsertParams);
1213-
1214-
// Step 2: Create and insert the judgetasks.
1215-
1216-
$testcases = $problem->getProblem()->getTestcases();
1217-
if (count($testcases) < 1) {
1218-
throw new BadRequestHttpException("No testcases set for problem {$problem->getProbid()}");
1219-
}
1220-
$judgetaskInsertParts = [];
1221-
/** @var Testcase $testcase */
1222-
foreach ($testcases as $testcase) {
1223-
$judgetaskInsertParts[] = sprintf(
1224-
'(%s, :testcase_id%d, :testcase_hash%d)',
1225-
implode(', ', $judgetaskDefaultParamNames),
1226-
$testcase->getTestcaseid(),
1227-
$testcase->getTestcaseid()
1228-
);
1229-
$judgetaskInsertParams[':testcase_id' . $testcase->getTestcaseid()] = $testcase->getTestcaseid();
1230-
$judgetaskInsertParams[':testcase_hash' . $testcase->getTestcaseid()] = $testcase->getMd5sumInput() . '_' . $testcase->getMd5sumOutput();
1231-
}
1232-
$judgetaskColumns = array_map(fn(string $column) => substr($column, 1), $judgetaskDefaultParamNames);
1233-
$judgetaskInsertQuery = sprintf(
1234-
'INSERT INTO judgetask (%s, testcase_id, testcase_hash) VALUES %s',
1235-
implode(', ', $judgetaskColumns),
1236-
implode(', ', $judgetaskInsertParts)
1237-
);
1238-
1239-
$judgetaskInsertParamsWithoutColon = [];
1240-
foreach ($judgetaskInsertParams as $key => $param) {
1241-
$key = str_replace(':', '', $key);
1242-
$judgetaskInsertParamsWithoutColon[$key] = $param;
1243-
}
1244-
1245-
$this->em->getConnection()->executeQuery($judgetaskInsertQuery, $judgetaskInsertParamsWithoutColon);
1246-
1247-
// Step 3: Fetch the judgetasks ID's per testcase.
1248-
$judgetaskData = $this->em->getConnection()->executeQuery(
1249-
'SELECT judgetaskid, testcase_id FROM judgetask WHERE jobid = :jobid ORDER BY judgetaskid',
1250-
['jobid' => $judging->getJudgingid()]
1251-
)->fetchAllAssociative();
1252-
1253-
// Step 4: Create and insert the corresponding judging runs.
1254-
$judgingRunInsertParams = [':judgingid' => $judging->getJudgingid()];
1255-
$judgingRunInsertParts = [];
1256-
foreach ($judgetaskData as $judgetaskItem) {
1257-
$judgingRunInsertParts[] = sprintf(
1258-
'(:judgingid, :testcaseid%d, :judgetaskid%d)',
1259-
$judgetaskItem['judgetaskid'],
1260-
$judgetaskItem['judgetaskid']
1261-
);
1262-
$judgingRunInsertParams[':testcaseid' . $judgetaskItem['judgetaskid']] = $judgetaskItem['testcase_id'];
1263-
$judgingRunInsertParams[':judgetaskid' . $judgetaskItem['judgetaskid']] = $judgetaskItem['judgetaskid'];
1264-
}
1265-
$judgingRunInsertQuery = sprintf(
1266-
'INSERT INTO judging_run (judgingid, testcaseid, judgetaskid) VALUES %s',
1267-
implode(', ', $judgingRunInsertParts)
1268-
);
1269-
1270-
$judgingRunInsertParamsWithoutColon = [];
1271-
foreach ($judgingRunInsertParams as $key => $param) {
1272-
$key = str_replace(':', '', $key);
1273-
$judgingRunInsertParamsWithoutColon[$key] = $param;
1274-
}
1275-
1276-
$this->em->getConnection()->executeQuery($judgingRunInsertQuery, $judgingRunInsertParamsWithoutColon);
1176+
$this->actuallyCreateJudgetasks($priority, $judging);
12771177

12781178
$team = $submission->getTeam();
12791179
$result = $this->em->createQueryBuilder()
@@ -1651,4 +1551,118 @@ public function getScoreboardZip(
16511551

16521552
return Utils::streamZipFile($tempFilename, 'contest.zip');
16531553
}
1554+
1555+
private function allowJudge(ContestProblem $problem, Submission $submission, Language $language, bool $manualRequest): bool
1556+
{
1557+
if (!$problem->getAllowJudge() || !$language->getAllowJudge()) {
1558+
return false;
1559+
}
1560+
$evalOnDemand = false;
1561+
// We have 2 cases, the problem picks the global value or the value is set.
1562+
if ($problem->determineOnDemand($this->config->get('lazy_eval_results'))) {
1563+
$evalOnDemand = true;
1564+
1565+
// Special case, we're shadow and someone submits on our side in that case
1566+
// we're not super lazy.
1567+
if ($this->config->get('data_source') === DOMJudgeService::DATA_SOURCE_CONFIGURATION_AND_LIVE_EXTERNAL
1568+
&& $submission->getExternalid() === null) {
1569+
$evalOnDemand = false;
1570+
}
1571+
if ($manualRequest) {
1572+
// When explicitly requested, judge the submission.
1573+
$evalOnDemand = false;
1574+
}
1575+
}
1576+
return !$evalOnDemand;
1577+
}
1578+
1579+
private function actuallyCreateJudgetasks(int $priority, Judging $judging): void
1580+
{
1581+
$submission = $judging->getSubmission();
1582+
$problem = $submission->getContestProblem();
1583+
// We use a mass insert query, since that is way faster than doing a separate insert for each testcase.
1584+
// We first insert judgetasks, then select their ID's and finally insert the judging runs.
1585+
1586+
// Step 1: Create the template for the judgetasks.
1587+
$compileExecutable = $submission->getLanguage()->getCompileExecutable()->getImmutableExecutable();
1588+
$judgetaskInsertParams = [
1589+
':type' => JudgeTaskType::JUDGING_RUN,
1590+
':submitid' => $submission->getSubmitid(),
1591+
':priority' => $priority,
1592+
':jobid' => $judging->getJudgingid(),
1593+
':uuid' => $judging->getUuid(),
1594+
':compile_script_id' => $compileExecutable->getImmutableExecId(),
1595+
':compare_script_id' => $this->getImmutableCompareExecutable($problem)->getImmutableExecId(),
1596+
':run_script_id' => $this->getImmutableRunExecutable($problem)->getImmutableExecId(),
1597+
':compile_config' => $this->getCompileConfig($submission),
1598+
':run_config' => $this->getRunConfig($problem, $submission),
1599+
':compare_config' => $this->getCompareConfig($problem),
1600+
];
1601+
1602+
$judgetaskDefaultParamNames = array_keys($judgetaskInsertParams);
1603+
1604+
// Step 2: Create and insert the judgetasks.
1605+
1606+
$testcases = $problem->getProblem()->getTestcases();
1607+
if (count($testcases) < 1) {
1608+
throw new BadRequestHttpException("No testcases set for problem {$problem->getProbid()}");
1609+
}
1610+
$judgetaskInsertParts = [];
1611+
/** @var Testcase $testcase */
1612+
foreach ($testcases as $testcase) {
1613+
$judgetaskInsertParts[] = sprintf(
1614+
'(%s, :testcase_id%d, :testcase_hash%d)',
1615+
implode(', ', $judgetaskDefaultParamNames),
1616+
$testcase->getTestcaseid(),
1617+
$testcase->getTestcaseid()
1618+
);
1619+
$judgetaskInsertParams[':testcase_id' . $testcase->getTestcaseid()] = $testcase->getTestcaseid();
1620+
$judgetaskInsertParams[':testcase_hash' . $testcase->getTestcaseid()] = $testcase->getMd5sumInput() . '_' . $testcase->getMd5sumOutput();
1621+
}
1622+
$judgetaskColumns = array_map(fn(string $column) => substr($column, 1), $judgetaskDefaultParamNames);
1623+
$judgetaskInsertQuery = sprintf(
1624+
'INSERT INTO judgetask (%s, testcase_id, testcase_hash) VALUES %s',
1625+
implode(', ', $judgetaskColumns),
1626+
implode(', ', $judgetaskInsertParts)
1627+
);
1628+
1629+
$judgetaskInsertParamsWithoutColon = [];
1630+
foreach ($judgetaskInsertParams as $key => $param) {
1631+
$key = str_replace(':', '', $key);
1632+
$judgetaskInsertParamsWithoutColon[$key] = $param;
1633+
}
1634+
1635+
$this->em->getConnection()->executeQuery($judgetaskInsertQuery, $judgetaskInsertParamsWithoutColon);
1636+
1637+
// Step 3: Fetch the judgetasks ID's per testcase.
1638+
$judgetaskData = $this->em->getConnection()->executeQuery(
1639+
'SELECT judgetaskid, testcase_id FROM judgetask WHERE jobid = :jobid ORDER BY judgetaskid',
1640+
['jobid' => $judging->getJudgingid()]
1641+
)->fetchAllAssociative();
1642+
1643+
// Step 4: Create and insert the corresponding judging runs.
1644+
$judgingRunInsertParams = [':judgingid' => $judging->getJudgingid()];
1645+
$judgingRunInsertParts = [];
1646+
foreach ($judgetaskData as $judgetaskItem) {
1647+
$judgingRunInsertParts[] = sprintf(
1648+
'(:judgingid, :testcaseid%d, :judgetaskid%d)',
1649+
$judgetaskItem['judgetaskid'],
1650+
$judgetaskItem['judgetaskid']
1651+
);
1652+
$judgingRunInsertParams[':testcaseid' . $judgetaskItem['judgetaskid']] = $judgetaskItem['testcase_id'];
1653+
$judgingRunInsertParams[':judgetaskid' . $judgetaskItem['judgetaskid']] = $judgetaskItem['judgetaskid'];
1654+
}
1655+
$judgingRunInsertQuery = sprintf(
1656+
'INSERT INTO judging_run (judgingid, testcaseid, judgetaskid) VALUES %s',
1657+
implode(', ', $judgingRunInsertParts)
1658+
);
1659+
1660+
$judgingRunInsertParamsWithoutColon = [];
1661+
foreach ($judgingRunInsertParams as $key => $param) {
1662+
$key = str_replace(':', '', $key);
1663+
$judgingRunInsertParamsWithoutColon[$key] = $param;
1664+
}
1665+
1666+
$this->em->getConnection()->executeQuery($judgingRunInsertQuery, $judgingRunInsertParamsWithoutColon);
1667+
}
16541668
}

0 commit comments

Comments
 (0)