|
16 | 16 | use Doctrine\ORM\EntityManagerInterface; |
17 | 17 | use Doctrine\ORM\NonUniqueResultException; |
18 | 18 | use Doctrine\ORM\NoResultException; |
| 19 | +use Ramsey\Uuid\Uuid; |
19 | 20 |
|
20 | 21 | class RejudgingService |
21 | 22 | { |
@@ -99,43 +100,62 @@ public function createRejudging( |
99 | 100 | } |
100 | 101 |
|
101 | 102 |
|
102 | | - $this->em->wrapInTransaction(function () use ( |
103 | | - $priority, |
104 | | - $singleJudging, |
105 | | - $judging, |
106 | | - $rejudging |
107 | | - ) { |
108 | | - $this->em->getConnection()->executeStatement( |
109 | | - 'UPDATE submission SET rejudgingid = :rejudgingid WHERE submitid = :submitid AND rejudgingid IS NULL', |
110 | | - [ |
111 | | - 'rejudgingid' => $rejudging->getRejudgingid(), |
112 | | - 'submitid' => $judging->getSubmissionId(), |
113 | | - ] |
114 | | - ); |
115 | | - |
116 | | - if ($singleJudging) { |
117 | | - $teamid = $judging->getSubmission()->getTeamId(); |
118 | | - if ($teamid) { |
119 | | - $this->em->getConnection()->executeStatement( |
120 | | - 'UPDATE team SET judging_last_started = null WHERE teamid = :teamid', |
121 | | - [ 'teamid' => $teamid ] |
122 | | - ); |
123 | | - } |
| 103 | + // $this->>em->wrapInTransaction flushes the entity manager, which is pretty slow. |
| 104 | + // So use the direct connection transaction API here. |
| 105 | + $this->em->getConnection()->beginTransaction(); |
| 106 | + |
| 107 | + $this->em->getConnection()->executeStatement( |
| 108 | + 'UPDATE submission SET rejudgingid = :rejudgingid WHERE submitid = :submitid AND rejudgingid IS NULL', |
| 109 | + [ |
| 110 | + 'rejudgingid' => $rejudging->getRejudgingid(), |
| 111 | + 'submitid' => $judging->getSubmissionId(), |
| 112 | + ] |
| 113 | + ); |
| 114 | + |
| 115 | + if ($singleJudging) { |
| 116 | + $teamid = $judging->getSubmission()->getTeamId(); |
| 117 | + if ($teamid) { |
| 118 | + $this->em->getConnection()->executeStatement( |
| 119 | + 'UPDATE team SET judging_last_started = null WHERE teamid = :teamid', |
| 120 | + [ 'teamid' => $teamid ] |
| 121 | + ); |
124 | 122 | } |
| 123 | + } |
125 | 124 |
|
126 | | - // Give back judging, create a new one. |
127 | | - $newJudging = new Judging(); |
128 | | - $newJudging |
129 | | - ->setContest($judging->getContest()) |
130 | | - ->setValid(false) |
131 | | - ->setSubmission($judging->getSubmission()) |
132 | | - ->setOriginalJudging($judging) |
133 | | - ->setRejudging($rejudging); |
134 | | - $this->em->persist($newJudging); |
135 | | - $this->em->flush(); |
136 | | - |
137 | | - $this->dj->maybeCreateJudgeTasks($newJudging, $priority); |
138 | | - }); |
| 125 | + // Give back judging, create a new one. |
| 126 | + // Use a direct query to speed things up. |
| 127 | + $this->em->getConnection()->executeStatement( |
| 128 | + 'INSERT INTO judging (cid, valid, submitid, prevjudgingid, rejudgingid, uuid) |
| 129 | + VALUES (:cid, 0, :submitid, :prevjudgingid, :rejudgingid, :uuid)', |
| 130 | + [ |
| 131 | + 'cid' => $judging->getContest()->getCid(), |
| 132 | + 'submitid' => $judging->getSubmissionId(), |
| 133 | + 'prevjudgingid' => $judging->getJudgingId(), |
| 134 | + 'rejudgingid' => $rejudging->getRejudgingid(), |
| 135 | + 'uuid' => Uuid::uuid4()->toString(), |
| 136 | + ] |
| 137 | + ); |
| 138 | + $newJudgingId = $this->em->getConnection()->lastInsertId(); |
| 139 | + $newJudging = $this->em->getRepository(Judging::class) |
| 140 | + ->createQueryBuilder('j') |
| 141 | + ->join('j.submission', 's') |
| 142 | + ->join('s.contest_problem', 'cp') |
| 143 | + ->join('s.language', 'l') |
| 144 | + ->join('l.compile_executable', 'e') |
| 145 | + ->join('cp.problem', 'p') |
| 146 | + ->leftJoin('p.compare_executable', 'ce') |
| 147 | + ->leftJoin('ce.immutableExecutable', 'ice') |
| 148 | + ->leftJoin('p.run_executable', 're') |
| 149 | + ->leftJoin('re.immutableExecutable', 'ire') |
| 150 | + ->select('j', 's', 'cp', 'l', 'e', 'p', 'ce', 'ice', 're', 'ire') |
| 151 | + ->andWhere('j.judgingid = :judgingid') |
| 152 | + ->setParameter('judgingid', $newJudgingId) |
| 153 | + ->getQuery() |
| 154 | + ->getSingleResult(); |
| 155 | + |
| 156 | + $this->dj->maybeCreateJudgeTasks($newJudging, $priority); |
| 157 | + |
| 158 | + $this->em->getConnection()->commit(); |
139 | 159 |
|
140 | 160 | if (!$first) { |
141 | 161 | $log .= ', '; |
|
0 commit comments