|
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