Recover transcripts falsely marked orphaned mid-run.

Keep finishing Whisper jobs from overwriting a superseded run, while restoring results when orphan detection failed the same run too early.
This commit is contained in:
ben
2026-08-12 15:34:36 +02:00
parent 21b17c7657
commit 3498861184
+65 -16
View File
@@ -76,26 +76,16 @@ class TranscribeRecording implements ShouldQueue
},
);
if (! $this->recording->ownsTranscriptionRun($this->runStartedAt)) {
if (! $this->claimSuccessfulTranscript($text)) {
return;
}
$this->reportIfOwned('Saving transcript…', 90);
if (! $this->recording->ownsTranscriptionRun($this->runStartedAt)) {
return;
}
$this->recording->forceFill([
'transcript' => $text,
'transcription_status' => 'done',
'transcription_progress' => 'Transcription complete',
'transcription_percent' => 100,
'transcription_error' => null,
'transcribed_at' => now(),
])->save();
} catch (Throwable $e) {
if (! $this->recording->ownsTranscriptionRun($this->runStartedAt)) {
Log::warning('Transcription exception ignored after run was superseded', [
'recording_id' => $this->recording->id,
'message' => $e->getMessage(),
]);
return;
}
@@ -103,6 +93,7 @@ class TranscribeRecording implements ShouldQueue
'recording_id' => $this->recording->id,
'driver' => $this->recording->transcription_driver,
'message' => $e->getMessage(),
'exception' => $e::class,
]);
$this->recording->markTranscriptionFailed($e->getMessage());
@@ -127,6 +118,64 @@ class TranscribeRecording implements ShouldQueue
);
}
/**
* Persist a finished transcript when this job still owns the run.
*
* Also recovers runs that were falsely marked failed by orphan detection
* while Whisper was still working.
*/
private function claimSuccessfulTranscript(string $text): bool
{
$this->recording->refresh();
if ($this->recording->ownsTranscriptionRun($this->runStartedAt)) {
$this->reportIfOwned('Saving transcript…', 90);
$this->recording->refresh();
}
if ($this->recording->ownsTranscriptionRun($this->runStartedAt)) {
$this->recording->forceFill([
'transcript' => $text,
'transcription_status' => 'done',
'transcription_progress' => 'Transcription complete',
'transcription_percent' => 100,
'transcription_error' => null,
'transcribed_at' => now(),
])->save();
return true;
}
// Same run was wrongly marked failed as "orphaned" while Whisper was still running.
if (
$this->recording->transcription_status === 'failed'
&& $this->recording->matchesTranscriptionRun($this->runStartedAt)
&& str_contains((string) $this->recording->transcription_error, 'worker stopped')
) {
Log::warning('Recovering transcript after false orphan failure', [
'recording_id' => $this->recording->id,
]);
$this->recording->forceFill([
'transcript' => $text,
'transcription_status' => 'done',
'transcription_progress' => 'Transcription complete',
'transcription_percent' => 100,
'transcription_error' => null,
'transcribed_at' => now(),
])->save();
return true;
}
Log::info('Discarding transcript because transcription run was superseded', [
'recording_id' => $this->recording->id,
'status' => $this->recording->transcription_status,
]);
return false;
}
private function reportIfOwned(string $message, int $percent): void
{
if (! $this->recording->ownsTranscriptionRun($this->runStartedAt)) {