feat(worker): allow update_task_status to set Cancelled

This commit is contained in:
Mika Kuns
2026-07-27 15:02:50 +02:00
parent ec10b06848
commit cc823ec4f6
4 changed files with 47 additions and 7 deletions
@@ -9,7 +9,7 @@ public interface ITaskStateService
Task<TransitionResult> SubmitInteractiveForReviewAsync(string taskId, DateTime finishedAt, CancellationToken ct);
Task<TransitionResult> SubmitForChildrenAsync(string taskId, DateTime finishedAt, string? result, CancellationToken ct);
Task<TransitionResult> FailAsync(string taskId, DateTime finishedAt, string? error, CancellationToken ct);
Task<TransitionResult> CancelAsync(string taskId, DateTime finishedAt, CancellationToken ct);
Task<TransitionResult> CancelAsync(string taskId, DateTime finishedAt, CancellationToken ct, bool allowFromIdle = false);
Task<TransitionResult> ResetToIdleAsync(string taskId, CancellationToken ct);
Task<TransitionResult> ApproveReviewAsync(string taskId, CancellationToken ct);
@@ -241,7 +241,13 @@ public sealed class TaskStateService : ITaskStateService
return new TransitionResult(true, null);
}
public async Task<TransitionResult> CancelAsync(string taskId, DateTime finishedAt, CancellationToken ct)
// allowFromIdle: only the external update_task_status(Cancelled) path sets this — it lets
// an Idle task be retired without deleting it. Every other caller (hub CancelReview,
// PlanningChainCoordinator's chain-walk, batch cancel) relies on Idle staying a no-op here;
// PlanningChainCoordinator specifically uses "parked back to Idle" as a deliberate opt-out
// signal, so do not flip this default.
public async Task<TransitionResult> CancelAsync(
string taskId, DateTime finishedAt, CancellationToken ct, bool allowFromIdle = false)
{
List<string> cancelledChildIds;
await using (var ctx = await _dbFactory.CreateDbContextAsync(ct))
@@ -250,7 +256,8 @@ public sealed class TaskStateService : ITaskStateService
.Where(t => t.Id == taskId &&
(t.Status == TaskStatus.Running || t.Status == TaskStatus.Queued
|| t.Status == TaskStatus.WaitingForReview
|| t.Status == TaskStatus.WaitingForChildren))
|| t.Status == TaskStatus.WaitingForChildren
|| (allowFromIdle && t.Status == TaskStatus.Idle)))
.ExecuteUpdateAsync(s => s
.SetProperty(t => t.Status, TaskStatus.Cancelled)
.SetProperty(t => t.FinishedAt, finishedAt), ct);