fix(worker): queue dispatches skip the StartRunning re-claim
The picker claims Queued->Running atomically before dispatch; the new StartRunningAsync guard then rejected every queue-dispatched run. Add alreadyClaimed to RunAsync/ContinueAsync (queue passes true, override slot keeps the guard) and align the routing tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,7 @@ public sealed class TaskRunner
|
||||
_tokens = tokens;
|
||||
}
|
||||
|
||||
public async Task RunAsync(TaskEntity task, string slot, CancellationToken ct)
|
||||
public async Task RunAsync(TaskEntity task, string slot, CancellationToken ct, bool alreadyClaimed = false)
|
||||
{
|
||||
string? mcpToken = null;
|
||||
string? mcpConfigPath = null;
|
||||
@@ -98,11 +98,16 @@ public sealed class TaskRunner
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var startResult = await _state.StartRunningAsync(task.Id, now, ct);
|
||||
if (!startResult.Ok)
|
||||
// The queue picker claims Queued→Running atomically (incl. StartedAt) before
|
||||
// dispatching; only unclaimed dispatches (override slot) claim here.
|
||||
if (!alreadyClaimed)
|
||||
{
|
||||
_logger.LogWarning("Task {TaskId} skipped: StartRunningAsync rejected ({Reason})", task.Id, startResult.Reason);
|
||||
return;
|
||||
var startResult = await _state.StartRunningAsync(task.Id, now, ct);
|
||||
if (!startResult.Ok)
|
||||
{
|
||||
_logger.LogWarning("Task {TaskId} skipped: StartRunningAsync rejected ({Reason})", task.Id, startResult.Reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
await _broadcaster.TaskStarted(slot, task.Id, now);
|
||||
|
||||
@@ -167,7 +172,7 @@ public sealed class TaskRunner
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ContinueAsync(string taskId, string followUpPrompt, string slot, CancellationToken ct)
|
||||
public async Task ContinueAsync(string taskId, string followUpPrompt, string slot, CancellationToken ct, bool alreadyClaimed = false)
|
||||
{
|
||||
TaskEntity task;
|
||||
TaskRunEntity lastRun;
|
||||
@@ -213,11 +218,15 @@ public sealed class TaskRunner
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
var startResult = await _state.StartRunningAsync(taskId, now, ct);
|
||||
if (!startResult.Ok)
|
||||
// See RunAsync: queue dispatches arrive pre-claimed by the picker.
|
||||
if (!alreadyClaimed)
|
||||
{
|
||||
_logger.LogWarning("Task {TaskId} skipped: StartRunningAsync rejected ({Reason})", taskId, startResult.Reason);
|
||||
return;
|
||||
var startResult = await _state.StartRunningAsync(taskId, now, ct);
|
||||
if (!startResult.Ok)
|
||||
{
|
||||
_logger.LogWarning("Task {TaskId} skipped: StartRunningAsync rejected ({Reason})", taskId, startResult.Reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
await _broadcaster.TaskStarted(slot, taskId, now);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user