refactor(worker/queue): split queue waker and picker, auto-wake on enqueue
Slice 3 of the worker state and queue consolidation refactor. - Add IQueueWaker / QueueWaker (singleton holding the wake semaphore). - Add IQueuePicker / QueuePicker; raw SQL UPDATE...RETURNING moves out of TaskRepository.GetNextQueuedAgentTaskAsync (deleted) and now also filters on blocked_by_task_id IS NULL and writes started_at on claim. - TaskStateService takes IQueueWaker directly; the Func<QueueService> indirection is gone. State transitions to Queued auto-wake the dispatcher. - QueueService waits via the shared waker and dispatches via the picker. - Drop explicit _queue.WakeQueue() calls in WorkerHub.QueuePlanningSubtasksAsync and ExternalMcpService.AddTask. The hub WakeQueue endpoint stays for diagnostics, delegating to _waker.Wake(). - Migrate tests; pre-existing flaky AppSettings/ExternalMcp tests untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using ClaudeDo.Data;
|
||||
using ClaudeDo.Worker.Hub;
|
||||
using ClaudeDo.Worker.Planning;
|
||||
using ClaudeDo.Worker.Queue;
|
||||
using ClaudeDo.Worker.State;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
@@ -15,23 +16,31 @@ public static class TaskStateServiceBuilder
|
||||
TaskStateService State,
|
||||
PlanningChainCoordinator Chain,
|
||||
CapturingHubContext Hub,
|
||||
Func<int> WakeCount);
|
||||
Func<int> WakeCount,
|
||||
CountingQueueWaker Waker);
|
||||
|
||||
public static Built Build(IDbContextFactory<ClaudeDoDbContext> dbFactory)
|
||||
{
|
||||
var hub = new CapturingHubContext();
|
||||
var broadcaster = new HubBroadcaster(hub);
|
||||
var wakeCount = new int[1];
|
||||
var waker = new CountingQueueWaker();
|
||||
|
||||
TaskStateService? state = null;
|
||||
var chain = new PlanningChainCoordinator(dbFactory, () => state!);
|
||||
state = new TaskStateService(
|
||||
dbFactory,
|
||||
broadcaster,
|
||||
() => Interlocked.Increment(ref wakeCount[0]),
|
||||
waker,
|
||||
chain,
|
||||
NullLogger<TaskStateService>.Instance);
|
||||
|
||||
return new Built(state, chain, hub, () => Volatile.Read(ref wakeCount[0]));
|
||||
return new Built(state, chain, hub, () => waker.Count, waker);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CountingQueueWaker : IQueueWaker
|
||||
{
|
||||
private int _count;
|
||||
public int Count => Volatile.Read(ref _count);
|
||||
public void Wake() => Interlocked.Increment(ref _count);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user