Skip to content

Commit 1e221b4

Browse files
Only set end time when verdict is set.
Also calculate max run time only based on those runs.
1 parent fb7c3ca commit 1e221b4

File tree

5 files changed

+88
-19
lines changed

5 files changed

+88
-19
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20241122150726 extends AbstractMigration
14+
{
15+
public function getDescription(): string
16+
{
17+
return 'Add max runtime for verdict to judging';
18+
}
19+
20+
public function up(Schema $schema): void
21+
{
22+
// this up() migration is auto-generated, please modify it to your needs
23+
$this->addSql('ALTER TABLE judging ADD max_runtime_for_verdict NUMERIC(32, 9) UNSIGNED DEFAULT NULL COMMENT \'The maximum run time for all runs that resulted in the verdict\'');
24+
}
25+
26+
public function down(Schema $schema): void
27+
{
28+
// this down() migration is auto-generated, please modify it to your needs
29+
$this->addSql('ALTER TABLE judging DROP max_runtime_for_verdict');
30+
}
31+
32+
public function isTransactional(): bool
33+
{
34+
return false;
35+
}
36+
}

webapp/src/Controller/API/JudgehostController.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,10 +1023,25 @@ private function addSingleJudgingRun(
10231023
if (!$hasNullResults || $lazyEval !== DOMJudgeService::EVAL_FULL) {
10241024
// NOTE: setting endtime here determines in testcases_GET
10251025
// whether a next testcase will be handed out.
1026-
$this->logger->error('Judging %d is done, setting endtime, it had %d', [ $judging->getJudgingid(), $judging->getEndtime() ]);
1027-
$this->logger->error('Verdict is %s', [$result]);
1028-
$sendJudgingEvent = !$judging->getEndtime();
1029-
$judging->setEndtime(Utils::now());
1026+
// We want to set the endtime and max runtime only once (once the verdict is known),
1027+
// so that the API doesn't update these values once they are set.
1028+
// We also don't want to send judging events after the verdict is known.
1029+
if (!$judging->getEndtime()) {
1030+
$sendJudgingEvent = true;
1031+
$judging->setEndtime(Utils::now());
1032+
1033+
// Also calculate the max run time and set it
1034+
$maxRunTime = $this->em->createQueryBuilder()
1035+
->from(Judging::class, 'j')
1036+
->select('MAX(jr.runtime) AS maxruntime')
1037+
->leftJoin('j.runs', 'jr')
1038+
->andWhere('j.judgingid = :judgingid')
1039+
->andWhere('jr.runtime IS NOT NULL')
1040+
->setParameter('judgingid', $judging->getJudgingid())
1041+
->getQuery()
1042+
->getSingleScalarResult();
1043+
$judging->setMaxRuntimeForVerdict($maxRunTime);
1044+
}
10301045
$this->maybeUpdateActiveJudging($judging);
10311046
}
10321047
$this->em->flush();

webapp/src/Controller/API/JudgementController.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ protected function getQueryBuilder(Request $request): QueryBuilder
104104
{
105105
$queryBuilder = $this->em->createQueryBuilder()
106106
->from(Judging::class, 'j')
107-
->select('j, c, s, MAX(jr.runtime) AS maxruntime')
107+
->select('j, c, s')
108108
->leftJoin('j.contest', 'c')
109109
->leftJoin('j.submission', 's')
110110
->leftJoin('j.rejudging', 'r')
@@ -161,12 +161,10 @@ protected function getIdField(): string
161161
return 'j.judgingid';
162162
}
163163

164-
public function transformObject($object): JudgingWrapper
164+
public function transformObject($judging): JudgingWrapper
165165
{
166166
/** @var Judging $judging */
167-
$judging = $object[0];
168-
$maxRunTime = $object['maxruntime'] === null ? null : (float)$object['maxruntime'];
169167
$judgementTypeId = $judging->getResult() ? $this->verdicts[$judging->getResult()] : null;
170-
return new JudgingWrapper($judging, $maxRunTime, $judgementTypeId);
168+
return new JudgingWrapper($judging, $judgementTypeId);
171169
}
172170
}

webapp/src/DataTransferObject/JudgingWrapper.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,7 @@ class JudgingWrapper
1111
public function __construct(
1212
#[Serializer\Inline]
1313
protected readonly Judging $judging,
14-
#[Serializer\Exclude]
15-
protected readonly ?float $maxRunTime = null,
1614
#[Serializer\SerializedName('judgement_type_id')]
1715
protected readonly ?string $judgementTypeId = null
1816
) {}
19-
20-
#[Serializer\VirtualProperty]
21-
#[Serializer\SerializedName('max_run_time')]
22-
#[Serializer\Type('float')]
23-
public function getMaxRunTime(): ?float
24-
{
25-
return Utils::roundedFloat($this->maxRunTime);
26-
}
2717
}

webapp/src/Entity/Judging.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ class Judging extends BaseApiEntity
5656
#[Serializer\Exclude]
5757
private string|float|null $endtime = null;
5858

59+
#[ORM\Column(
60+
type: 'decimal',
61+
precision: 32,
62+
scale: 9,
63+
nullable: true,
64+
options: ['comment' => 'The maximum runtime for all runs that resulted in the verdict', 'unsigned' => true]
65+
)]
66+
#[Serializer\Exclude]
67+
private string|float|null $maxRuntimeForVerdict = null;
68+
5969
#[ORM\Column(
6070
length: 32,
6171
nullable: true,
@@ -250,6 +260,26 @@ public function getRelativeEndTime(): ?string
250260
return $this->getEndtime() ? Utils::relTime($this->getEndtime() - $this->getContest()->getStarttime()) : null;
251261
}
252262

263+
public function setMaxRuntimeForVerdict(string|float $maxRuntimeForVerdict): Judging
264+
{
265+
$this->maxRuntimeForVerdict = $maxRuntimeForVerdict;
266+
return $this;
267+
}
268+
269+
public function getMaxRuntimeForVerdict(): string|float|null
270+
{
271+
return $this->maxRuntimeForVerdict;
272+
}
273+
274+
#[Serializer\VirtualProperty]
275+
#[Serializer\SerializedName('max_run_time')]
276+
#[Serializer\Type('float')]
277+
#[OA\Property(nullable: true)]
278+
public function getRoundedMaxRuntimeForVerdict(): ?float
279+
{
280+
return $this->maxRuntimeForVerdict ? Utils::roundedFloat((float)$this->maxRuntimeForVerdict) : null;
281+
}
282+
253283
public function setResult(?string $result): Judging
254284
{
255285
$this->result = $result;

0 commit comments

Comments
 (0)