fix(worker): address concurrency, cancellation, and resource issues
- claude process: run stdout/stderr reads without ct; rely on kill-on-cancel closing the pipes to unblock them — previously ReadLineAsync(ct) could hang, stalling task slots and shutdown - task runner: terminal db writes (task_runs, MarkDone, MarkFailed, SetLogPath) now use CancellationToken.None; RunOnceAsync catches OCE and finalizes the run row so ContinueAsync can resume - task repository: GetNextQueuedAgentTaskAsync is now a single UPDATE ... RETURNING statement — closes TOCTOU window where two loop iterations could dispatch the same queued task - queue service: dispose CancellationTokenSource in slot-completion ContinueWith to stop leaking wait handles - git service: register ct.Kill(processTree), drain reads without ct, always reap via WaitForExitAsync(None) — no more git zombies on cancelled worktree ops - worktree manager: branch name uses full task id (dashes stripped) instead of 8-char prefix, eliminating collision risk Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -71,6 +71,7 @@ public sealed class QueueService : BackgroundService
|
||||
_ = RunInSlotAsync(task, "override", cts.Token).ContinueWith(_ =>
|
||||
{
|
||||
lock (_lock) { _overrideSlot = null; }
|
||||
cts.Dispose();
|
||||
}, TaskScheduler.Default);
|
||||
}
|
||||
}
|
||||
@@ -94,6 +95,7 @@ public sealed class QueueService : BackgroundService
|
||||
_ = RunContinueInSlotAsync(taskId, followUpPrompt, cts.Token).ContinueWith(_ =>
|
||||
{
|
||||
lock (_lock) { _overrideSlot = null; }
|
||||
cts.Dispose();
|
||||
}, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
@@ -155,6 +157,7 @@ public sealed class QueueService : BackgroundService
|
||||
_ = RunInSlotAsync(task, "queue", cts.Token).ContinueWith(_ =>
|
||||
{
|
||||
lock (_lock) { _queueSlot = null; }
|
||||
cts.Dispose();
|
||||
WakeQueue(); // Check for next task immediately.
|
||||
}, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user