Merge task branch for: fix(worker): FailAsync-Guard untersuchen — ist Queued→Failed erreichbar/gewollt?
This commit is contained in:
@@ -69,7 +69,7 @@ Allowed transitions (enforced by `TaskStateService`):
|
|||||||
|
|
||||||
```
|
```
|
||||||
Idle → Queued | Running (RunNow)
|
Idle → Queued | Running (RunNow)
|
||||||
Queued → Running | Cancelled | Idle | Failed (runner guard)
|
Queued → Running | Cancelled | Idle | Failed (OverrideSlotService preflight gap: RunAsync can fail before StartRunningAsync is called)
|
||||||
Running → WaitingForReview (standalone success, no children)
|
Running → WaitingForReview (standalone success, no children)
|
||||||
| WaitingForChildren (parent with pending children)
|
| WaitingForChildren (parent with pending children)
|
||||||
| Done (planning/improvement child success) | Failed | Cancelled
|
| Done (planning/improvement child success) | Failed | Cancelled
|
||||||
|
|||||||
@@ -198,6 +198,9 @@ public sealed class TaskStateService : ITaskStateService
|
|||||||
{
|
{
|
||||||
await using (var ctx = await _dbFactory.CreateDbContextAsync(ct))
|
await using (var ctx = await _dbFactory.CreateDbContextAsync(ct))
|
||||||
{
|
{
|
||||||
|
// Queued is intentional: OverrideSlotService dispatches RunAsync before calling
|
||||||
|
// StartRunningAsync, so a preflight failure (list not found, worktree setup) can
|
||||||
|
// reach MarkFailed while the task is still Queued in the DB.
|
||||||
var affected = await ctx.Tasks
|
var affected = await ctx.Tasks
|
||||||
.Where(t => t.Id == taskId &&
|
.Where(t => t.Id == taskId &&
|
||||||
(t.Status == TaskStatus.Running || t.Status == TaskStatus.Queued))
|
(t.Status == TaskStatus.Running || t.Status == TaskStatus.Queued))
|
||||||
|
|||||||
@@ -232,6 +232,21 @@ public sealed class TaskStateServiceTests : IDisposable
|
|||||||
Assert.Equal("boom", t.Result);
|
Assert.Equal("boom", t.Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task FailAsync_FromQueued_TransitionsToFailed()
|
||||||
|
{
|
||||||
|
// OverrideSlotService can call MarkFailed before StartRunningAsync when a
|
||||||
|
// preflight step (list lookup, worktree setup) fails — the task is still Queued.
|
||||||
|
var id = await SeedTaskAsync(TaskStatus.Queued);
|
||||||
|
|
||||||
|
var result = await _sut.FailAsync(id, DateTime.UtcNow, "list not found", default);
|
||||||
|
|
||||||
|
Assert.True(result.Ok);
|
||||||
|
var t = await GetTaskAsync(id);
|
||||||
|
Assert.Equal(TaskStatus.Failed, t.Status);
|
||||||
|
Assert.Equal("list not found", t.Result);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FailAsync_FromDone_Rejects()
|
public async Task FailAsync_FromDone_Rejects()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user