@@ -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