Skip to content

Commit 6035ff8

Browse files
committed
Remove support for multiple endpoints from judgedaemon.
This broke frequently without anyone reporting it, so there doesn't seem to be any usage. Removing it reduces the maintainance surface.
1 parent 1e27ed0 commit 6035ff8

File tree

1 file changed

+43
-61
lines changed

1 file changed

+43
-61
lines changed

judge/judgedaemon.main.php

Lines changed: 43 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class JudgeDaemon
2222
{
2323
private static ?JudgeDaemon $instance = null;
2424

25-
private array $endpoints = [];
25+
private ?array $endpoint = null;
2626
private array $domjudge_config = [];
2727
private string $myhost;
2828
private int $verbose = LOG_INFO;
@@ -35,8 +35,6 @@ class JudgeDaemon
3535
private ?string $lastrequest = '';
3636
private float $waittime = self::INITIAL_WAITTIME_SEC;
3737

38-
private ?string $endpointID = null;
39-
4038
private array $langexts = [];
4139

4240
private $lockfile;
@@ -221,10 +219,7 @@ private function initialize(): void
221219
error("chroot validation check failed");
222220
}
223221

224-
foreach (array_keys($this->endpoints) as $id) {
225-
$this->endpointID = $id;
226-
$this->registerJudgehost();
227-
}
222+
$this->registerJudgehost();
228223

229224
// Populate the DOMjudge configuration initially
230225
$this->djconfigRefresh();
@@ -248,34 +243,21 @@ private function initialize(): void
248243

249244
private function loop(): void
250245
{
251-
$endpointIDs = array_keys($this->endpoints);
252-
$currentEndpoint = 0;
253246
$lastWorkdir = null;
247+
$workdirpath = JUDGEDIR . "/$this->myhost/endpoint-" . $this->endpoint['id'];
248+
254249
while (true) {
255-
// If all endpoints are waiting, sleep for a bit.
256-
$dosleep = true;
257-
foreach ($this->endpoints as $id => $endpoint) {
258-
if ($endpoint['errorred']) {
259-
$this->endpointID = $id;
260-
$this->registerJudgehost();
261-
}
262-
if (!$endpoint['waiting']) {
263-
$dosleep = false;
264-
$this->waittime = self::INITIAL_WAITTIME_SEC;
265-
break;
266-
}
250+
if ($this->endpoint['errorred']) {
251+
$this->registerJudgehost();
267252
}
268-
// Sleep only if everything is "waiting" and only if we're looking at the first endpoint again.
269-
if ($dosleep && $currentEndpoint == 0) {
253+
254+
if ($this->endpoint['waiting']) {
270255
dj_sleep($this->waittime);
271256
$this->waittime = min($this->waittime * 2, self::MAXIMAL_WAITTIME_SEC);
257+
} else {
258+
$this->waittime = self::INITIAL_WAITTIME_SEC;
272259
}
273260

274-
// Cycle through endpoints.
275-
$currentEndpoint = ($currentEndpoint + 1) % count($this->endpoints);
276-
$this->endpointID = $endpointIDs[$currentEndpoint];
277-
$workdirpath = JUDGEDIR . "/$this->myhost/endpoint-$this->endpointID";
278-
279261
// Check whether we have received an exit signal
280262
if (function_exists('pcntl_signal_dispatch')) {
281263
pcntl_signal_dispatch();
@@ -308,12 +290,12 @@ private function loop(): void
308290
exit;
309291
}
310292

311-
if ($this->endpoints[$this->endpointID]['errorred']) {
293+
if ($this->endpoint['errorred']) {
312294
continue;
313295
}
314296

315297

316-
if ($this->endpoints[$this->endpointID]['waiting'] === false) {
298+
if ($this->endpoint['waiting'] === false) {
317299
$this->checkDiskSpace($workdirpath);
318300
}
319301

@@ -330,13 +312,13 @@ private function loop(): void
330312

331313
// Nothing returned -> no open work for us.
332314
if (empty($row)) {
333-
if (!$this->endpoints[$this->endpointID]["waiting"]) {
334-
$this->endpoints[$this->endpointID]["waiting"] = true;
315+
if (!$this->endpoint["waiting"]) {
316+
$this->endpoint["waiting"] = true;
335317
if ($lastWorkdir !== null) {
336318
$this->cleanupJudging($lastWorkdir);
337319
$lastWorkdir = null;
338320
}
339-
logmsg(LOG_INFO, "No submissions in queue (for endpoint $this->endpointID), waiting...");
321+
logmsg(LOG_INFO, "No submissions in queue (for endpoint " . $this->endpoint['id'] . "), waiting...");
340322
$judgehosts = $this->request('judgehosts', 'GET');
341323
if ($judgehosts !== null) {
342324
$judgehosts = dj_json_decode($judgehosts);
@@ -350,7 +332,7 @@ private function loop(): void
350332
}
351333

352334
// We have gotten a work packet.
353-
$this->endpoints[$this->endpointID]["waiting"] = false;
335+
$this->endpoint["waiting"] = false;
354336

355337
// All tasks are guaranteed to be of the same type.
356338
// If $row is empty, we already continued.
@@ -542,16 +524,16 @@ private function handlePrefetchTask(array $row, ?string &$lastWorkdir, string $w
542524
private function handleTask(string $type, array $row, ?string &$lastWorkdir, string $workdirpath): void
543525
{
544526
if ($type == 'try_again') {
545-
if (!$this->endpoints[$this->endpointID]['retrying']) {
527+
if (!$this->endpoint['retrying']) {
546528
logmsg(LOG_INFO, "API indicated to retry fetching work (this might take a while to clean up).");
547529
}
548-
$this->endpoints[$this->endpointID]['retrying'] = true;
530+
$this->endpoint['retrying'] = true;
549531
return;
550532
}
551-
$this->endpoints[$this->endpointID]['retrying'] = false;
533+
$this->endpoint['retrying'] = false;
552534

553535
logmsg(LOG_INFO,
554-
"⇝ Received " . sizeof($row) . " '" . $type . "' judge tasks (endpoint $this->endpointID)");
536+
"⇝ Received " . sizeof($row) . " '" . $type . "' judge tasks (endpoint " . $this->endpoint['id'] . ")");
555537

556538
if ($type == 'prefetch') {
557539
$this->handlePrefetchTask($row, $lastWorkdir, $workdirpath);
@@ -657,10 +639,12 @@ private function readCredentials(): void
657639
error("Error parsing REST API credentials. Invalid format in line $lineno.");
658640
}
659641
[$endpointID, $resturl, $restuser, $restpass] = $items;
660-
if (array_key_exists($endpointID, $this->endpoints)) {
661-
error("Error parsing REST API credentials. Duplicate endpoint ID '$endpointID' in line $lineno.");
642+
643+
if ($this->endpoint !== null) {
644+
error("Error parsing REST API credentials. Multiple endpoints are not supported.");
662645
}
663-
$this->endpoints[$endpointID] = [
646+
$this->endpoint = [
647+
"id" => $endpointID,
664648
"url" => $resturl,
665649
"user" => $restuser,
666650
"pass" => $restpass,
@@ -670,7 +654,7 @@ private function readCredentials(): void
670654
"retrying" => false,
671655
];
672656
}
673-
if (count($this->endpoints) <= 0) {
657+
if ($this->endpoint === null) {
674658
error("Error parsing REST API credentials: no endpoints found.");
675659
}
676660
}
@@ -687,11 +671,9 @@ private function setupCurlHandle(string $restuser, string $restpass): \CurlHandl
687671

688672
private function closeCurlHandles(): void
689673
{
690-
foreach ($this->endpoints as $id => $endpoint) {
691-
if (!empty($endpoint['ch'])) {
692-
curl_close($endpoint['ch']);
693-
unset($this->endpoints[$id]['ch']);
694-
}
674+
if (!empty($this->endpoint['ch'])) {
675+
curl_close($this->endpoint['ch']);
676+
unset($this->endpoint['ch']);
695677
}
696678
}
697679

@@ -708,8 +690,8 @@ private function request(string $url, string $verb = 'GET', $data = '', bool $fa
708690
$this->lastrequest = $url;
709691
}
710692

711-
$requestUrl = $this->endpoints[$this->endpointID]['url'] . "/" . $url;
712-
$curl_handle = $this->endpoints[$this->endpointID]['ch'];
693+
$requestUrl = $this->endpoint['url'] . "/" . $url;
694+
$curl_handle = $this->endpoint['ch'];
713695
if ($verb == 'GET') {
714696
$requestUrl .= '?' . $data;
715697
}
@@ -778,15 +760,15 @@ private function request(string $url, string $verb = 'GET', $data = '', bool $fa
778760
error($errstr);
779761
} else {
780762
warning($errstr);
781-
$this->endpoints[$this->endpointID]['errorred'] = true;
763+
$this->endpoint['errorred'] = true;
782764
return null;
783765
}
784766
}
785767

786-
if ($this->endpoints[$this->endpointID]['errorred']) {
787-
$this->endpoints[$this->endpointID]['errorred'] = false;
788-
$this->endpoints[$this->endpointID]['waiting'] = false;
789-
logmsg(LOG_NOTICE, "Reconnected to endpoint $this->endpointID.");
768+
if ($this->endpoint['errorred']) {
769+
$this->endpoint['errorred'] = false;
770+
$this->endpoint['waiting'] = false;
771+
logmsg(LOG_NOTICE, "Reconnected to endpoint " . $this->endpoint['id'] . ".");
790772
}
791773

792774
return $response;
@@ -1083,7 +1065,7 @@ private function fetchExecutableInternal(
10831065

10841066
private function registerJudgehost(): void
10851067
{
1086-
$endpoint = &$this->endpoints[$this->endpointID];
1068+
$endpoint = &$this->endpoint;
10871069

10881070
// Only try to register every 30s.
10891071
$now = time();
@@ -1093,11 +1075,11 @@ private function registerJudgehost(): void
10931075
}
10941076
$endpoint['last_attempt'] = $now;
10951077

1096-
logmsg(LOG_NOTICE, "Registering judgehost on endpoint $this->endpointID: " . $endpoint['url']);
1097-
$this->endpoints[$this->endpointID]['ch'] = $this->setupCurlHandle($endpoint['user'], $endpoint['pass']);
1078+
logmsg(LOG_NOTICE, "Registering judgehost on endpoint " . $this->endpoint['id'] . ": " . $endpoint['url']);
1079+
$this->endpoint['ch'] = $this->setupCurlHandle($endpoint['user'], $endpoint['pass']);
10981080

10991081
// Create directory where to test submissions
1100-
$workdirpath = JUDGEDIR . "/$this->myhost/endpoint-$this->endpointID";
1082+
$workdirpath = JUDGEDIR . "/$this->myhost/endpoint-" . $this->endpoint['id'];
11011083
if (!$this->runCommandSafe(['mkdir', '-p', "$workdirpath/testcase"])) {
11021084
error("Could not create $workdirpath");
11031085
}
@@ -1108,7 +1090,7 @@ private function registerJudgehost(): void
11081090
// they have and will not be finished. Give them back.
11091091
$unfinished = $this->request('judgehosts', 'POST', ['hostname' => urlencode($this->myhost)], false);
11101092
if ($unfinished === null) {
1111-
logmsg(LOG_WARNING, "Registering judgehost on endpoint $this->endpointID failed.");
1093+
logmsg(LOG_WARNING, "Registering judgehost on endpoint " . $this->endpoint['id'] . " failed.");
11121094
} else {
11131095
$unfinished = dj_json_decode($unfinished);
11141096
foreach ($unfinished as $jud) {
@@ -1683,8 +1665,8 @@ private function reportJudgingRun(array $judgeTask, array $new_judging_run, bool
16831665

16841666
// The child should use its own curl handle to avoid issues with sharing handles
16851667
// between processes.
1686-
$endpoint = $this->endpoints[$this->endpointID];
1687-
$this->endpoints[$this->endpointID]['ch'] = $this->setupCurlHandle($endpoint['user'], $endpoint['pass']);
1668+
$endpoint = $this->endpoint;
1669+
$this->endpoint['ch'] = $this->setupCurlHandle($endpoint['user'], $endpoint['pass']);
16881670
}
16891671
} elseif ($asynchronous) {
16901672
logmsg(LOG_WARNING, "pcntl extension not available, reporting result for jt$judgeTaskId synchronously.");

0 commit comments

Comments
 (0)