Files
vkv/app/Jobs/RebuildClaimedLogResultsJob.php
Zdeněk Burda 41e3ce6f25 Initial commit
2026-01-09 21:26:40 +01:00

78 lines
2.3 KiB
PHP

<?php
namespace App\Jobs;
use App\Models\EvaluationLock;
use App\Models\EvaluationRun;
use App\Models\Log;
use App\Jobs\UpsertClaimedLogResultJob;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
/**
* Job: RebuildClaimedLogResultsJob
*
* Znovu postaví claimed projekci pro celé kolo a přepočítá pořadí.
*/
class RebuildClaimedLogResultsJob implements ShouldQueue
{
use Queueable;
public function __construct(
protected int $evaluationRunId
) {
}
public function handle(): void
{
$run = EvaluationRun::find($this->evaluationRunId);
if (! $run) {
return;
}
$lock = EvaluationLock::acquire(
key: "evaluation:claimed-rebuild:round:{$run->round_id}",
run: $run,
ttl: 1800
);
if (! $lock) {
return;
}
try {
// Rebuild je deterministická rekonstrukce claimed projekce pro celé kolo.
$total = Log::where('round_id', $run->round_id)->count();
$run->update([
'status' => 'RUNNING',
'current_step' => 'rebuild_claimed',
'progress_total' => $total,
'progress_done' => 0,
'started_at' => $run->started_at ?? now(),
]);
$processed = 0;
Log::where('round_id', $run->round_id)
->chunkById(50, function ($logs) use (&$processed, $run) {
foreach ($logs as $log) {
$processed++;
// Projekce claimed výsledků je synchronní, aby rebuild skončil konzistentně.
UpsertClaimedLogResultJob::dispatchSync($log->id);
$run->update(['progress_done' => $processed]);
}
});
// Po projekci je nutné přepočítat pořadí claimed scoreboardu.
RecalculateClaimedRanksJob::dispatchSync($run->id);
$run->update([
'status' => 'SUCCEEDED',
'current_step' => 'rebuild_claimed_done',
'finished_at' => now(),
]);
} finally {
EvaluationLock::release("evaluation:claimed-rebuild:round:{$run->round_id}", $run);
}
}
}