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); } } }