fix(worker): fail the task when a queue slot runner throws

RunInSlotAsync only logged an unexpected exception, leaving a task stuck
Running in the DB forever with the UI never notified (the raw-SQL queue
claim that put it there never broadcasts). Cancellation is handled
separately and left alone, since the cancel path already wrote the
terminal status.
This commit is contained in:
mika kuns
2026-08-07 09:35:26 +02:00
parent ac099dd1a8
commit c1184adc92
2 changed files with 235 additions and 0 deletions
+19
View File
@@ -343,9 +343,28 @@ public sealed class QueueService : BackgroundService
await _runner.RunAsync(task, "queue", ct, alreadyClaimed: true);
}
catch (OperationCanceledException)
{
// Cancellation is driven by the cancel path, which already wrote the terminal status.
// Marking the task Failed here would be a regression (it would stomp Cancelled).
_logger.LogInformation("Slot runner cancelled for task {TaskId}", taskId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Slot runner error for task {TaskId}", taskId);
// The picker already committed status='running' before this ran. Without this the
// task stays Running forever and the UI never hears about it — it keeps showing the
// pre-claim status because the raw-SQL claim itself never broadcasts.
try
{
await _state.FailAsync(taskId, DateTime.UtcNow,
$"Slot runner error: {ex.Message}", CancellationToken.None);
}
catch (Exception failEx)
{
_logger.LogError(failEx, "Could not mark task {TaskId} as failed after a slot error", taskId);
}
}
}
}