Commit Graph

9 Commits

Author SHA1 Message Date
b7b05bb4e3 CUB-200: fix event-loss race — register handlers before readLoop starts
Some checks failed
Dev Build & Deploy / test-and-build (pull_request) Failing after 0s
Dev Build & Deploy / docker-build-push (pull_request) Has been skipped
Move registerEventHandlers() call before the readLoop goroutine starts
in connectAndRun(). This eliminates the startup window where live gateway
events were actively read and dropped as 'unhandled' because handler
registration happened only after initialSync completed.

The handlers only depend on c.agents and c.broker, which are wired in the
constructor — they do not require initialSync to have completed.

Also adds TestConnectAndRun_EventNotLostDuringSync regression test that
sends a live presence event during initial sync and asserts it is not lost.

All gateway tests pass with -race.
2026-05-20 21:52:39 +00:00
d370d5ec23 CUB-200: fix WS initial sync ordering — start readLoop before initialSync
Some checks failed
Dev Build & Deploy / test-and-build (pull_request) Failing after 0s
Dev Build & Deploy / docker-build-push (pull_request) Has been skipped
The root cause of the initial sync timeout was that connectAndRun called
initialSync (which uses Send/RPC) before starting readLoop, but Send's
response delivery depends on readLoop→routeFrame→handleResponse. Without
the readLoop running, agents.list and sessions.list would always time out.

Fix: start readLoop in a goroutine before calling initialSync so that
RPC responses are properly routed back to pending Send() calls. After
initialSync completes, event handlers are registered and MarkWSReady
is called. The connectAndRun function then blocks on the readLoop
goroutine's completion.

Also added TestConnectAndRun_InitialSyncOrdering which verifies that
agents are persisted from initial sync (would hang/timeout under the
old ordering).
2026-05-20 21:42:31 +00:00
Dex
1b82e1d3a6 CUB-200: resolve merge conflicts with dev — adopt dev's consolidated workflows and improved Go gateway code
Some checks failed
Dev Build & Deploy / test-and-build (pull_request) Failing after 0s
Dev Build & Deploy / docker-build-push (pull_request) Has been skipped
2026-05-20 21:26:17 +00:00
Dex
4569fef11d CUB-203: fix Grimm review blocking issues (PR #41)
Some checks failed
Dev Build / deploy-dev (pull_request) Blocked by required conditions
Dev Build / build-test (pull_request) Waiting to run
Build (Dev) / build-go-backend (pull_request) Failing after 0s
Build (Dev) / trigger-deploy (pull_request) Has been skipped
Build (Dev) / build-frontend (pull_request) Failing after 1s
openclaw/grimm-review All 11 findings resolved. Approved.
🔴 readLoop race: replace WriteControl close with ctx-done goroutine that closes conn
🔴 duplicate event handlers: clear handlers map before re-registering on reconnect
🔴 sync.go CurrentTask abuse: add DisplayName field to UpdateAgentRequest, use it
🔴 sync.go newRole dead code: add Role field to UpdateAgentRequest, use it
🔴 events.go handlePresence DB/SSE inconsistency: pass LastActivityAt in update, don't mutate after DB
🔴 events.go handleAgentConfig DB/SSE inconsistency: use DisplayName/Role fields in update
🟠 Send() nil-conn panic: check conn != nil before WriteJSON
🟠 readLoop prompt ctx cancellation: fixed by item #1
🟠 backoff never resets: reset to initialBackoff after successful connectAndRun
🟠 MarkWSReady double-close race: use sync.Once in Client
Extra json:"-" dead fields: removed from sessionChangedPayload, presencePayload, agentConfigPayload
UpdateAgentRequest: added DisplayName, Role, LastActivityAt fields
2026-05-20 11:47:11 +00:00
Dex
d28d6e8dac CUB-200: implement WebSocket gateway client with v3 protocol
Some checks are pending
Dev Build / build-test (pull_request) Waiting to run
Dev Build / deploy-dev (pull_request) Blocked by required conditions
Replace REST poller with WebSocket client as primary gateway connection:

- wsclient.go: WebSocket client with v3 handshake (connect.challenge →
  connect → hello-ok), frame routing (req/res/event), JSON-RPC Send(),
  auto-reconnect with exponential backoff (1s → 30s max)
- sync.go: Initial sync via agents.list + sessions.list RPCs, merge
  session runtime state into AgentCardData, broadcast fleet.update
- events.go: Real-time event handlers for sessions.changed, presence,
  and agent.config — DB update first, then SSE broadcast
- client.go: REST poller retained as fallback (WS is primary)
- config.go: Add GATEWAY_WS_URL and OPENCLAW_GATEWAY_TOKEN env vars
- main.go: Wire WS client as primary, REST as fallback
- .env.example: Document new WS config vars

Fallback: If WS connection fails, seeded demo data + REST polling
remain available.
2026-05-20 11:33:17 +00:00
Dex
e131798f3b CUB-204: wire WS client as primary, REST poller as fallback
Some checks failed
Dev Build / build-test (pull_request) Failing after 1s
Build (Dev) / trigger-deploy (pull_request) Has been skipped
openclaw/grimm-review REJECTED — 6 blocking issues
Build (Dev) / build-go-backend (pull_request) Failing after 0s
Build (Dev) / build-frontend (pull_request) Failing after 1s
- Rename GatewayURL/GatewayPollInterval → GatewayRestURL/GatewayRestPollInterval
- Change Docker-aware defaults (host.docker.internal instead of localhost)
- Client.Start() waits for WS readiness (30s timeout), falls back to REST
- Client.SetWSClient()/MarkWSReady() for WS→REST coordination
- WSClient.SetRESTClient() so WS notifies REST on successful handshake
- main.go wires both clients: WS primary, REST fallback with cross-references
- .env.example documents WS_GATEWAY_URL, GATEWAY_TOKEN, REST fallback vars
- docker-compose.yml adds WS_GATEWAY_URL and GATEWAY_TOKEN env vars
- reference/CONTROL_CENTER_CONTEXT.md documents architecture and startup sequence
2026-05-20 11:16:05 +00:00
Dex
9062f8fa8d CUB-202: add real-time event handlers for sessions.changed, presence, agent.config
Some checks failed
Dev Build / build-test (pull_request) Failing after 0s
2026-05-20 11:13:53 +00:00
Dex
60ba3e5b4f CUB-201: add initial sync via agents.list + sessions.list RPCs
Some checks failed
Dev Build / build-test (pull_request) Failing after 1s
- Create gateway/sync.go with initialSync method on WSClient
- Fetch agents via agents.list RPC, persist to AgentRepo
- Fetch sessions via sessions.list RPC, map status to AgentStatus
- Merge session state (status, sessionKey, tokens) into AgentCardData
- Broadcast merged fleet as fleet.update via SSE broker
- Trigger initialSync after hello-ok handshake
- Re-sync automatically on reconnect (connectAndRun calls initialSync)
- Handle unknown gateway fields gracefully via typed extraction
2026-05-20 11:07:23 +00:00
Dex
70d39b87d1 CUB-203: add WebSocket client scaffold for OpenClaw gateway v3
Some checks failed
Dev Build / build-test (pull_request) Failing after 14s
2026-05-20 11:02:21 +00:00