summaryrefslogtreecommitdiff
path: root/internal/api/server.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-26 05:45:19 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-26 05:45:19 +0000
commit2710eb8a3a58abbea95bd487797abbb3e67f0d0a (patch)
treea461743fb822306b82bf48196706f883d9d97353 /internal/api/server.go
parentb009880307298abea11efad92da2cd955afafe99 (diff)
fix: resolve dep-chain deadlock; broadcast task_started for UI visibility
With maxPerAgent=1, tasks with DependsOn were entering waitForDependencies while holding the per-agent slot, preventing the dependency from ever running. Fix: check deps before taking the slot. If not ready, requeue without holding activePerAgent. Also accept StateReady (leaf tasks) as a satisfied dependency, not just StateCompleted. Add startedCh to pool and broadcast task_started WebSocket event when a task transitions to RUNNING, so the UI immediately shows the running state during the clone phase instead of waiting for completion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/api/server.go')
-rw-r--r--internal/api/server.go13
1 files changed, 12 insertions, 1 deletions
diff --git a/internal/api/server.go b/internal/api/server.go
index fc9bd63..38108de 100644
--- a/internal/api/server.go
+++ b/internal/api/server.go
@@ -161,8 +161,19 @@ func (s *Server) routes() {
s.mux.Handle("GET /", http.FileServerFS(webui.Files))
}
-// forwardResults listens on the executor pool's result channel and broadcasts via WebSocket.
+// forwardResults listens on the executor pool's result and started channels and broadcasts via WebSocket.
func (s *Server) forwardResults() {
+ go func() {
+ for taskID := range s.pool.Started() {
+ event := map[string]interface{}{
+ "type": "task_started",
+ "task_id": taskID,
+ "timestamp": time.Now().UTC(),
+ }
+ data, _ := json.Marshal(event)
+ s.hub.Broadcast(data)
+ }
+ }()
for result := range s.pool.Results() {
s.processResult(result)
}