- Fix metrics: change MessagesTotal, ConnectionsTotal, DisconnectionsTotal from Gauge to Counter with proper _total naming convention - Fix broadcast write-error handling: failed clients now get properly removed with accurate metrics updates - Add graceful shutdown: SIGINT/SIGTERM handling with 10s timeout, CloseGoingAway frame sent to clients before disconnect - Add integration tests: 11 tests using real WebSocket connections covering connect, broadcast, disconnect, concurrency, and shutdown - Fix example client port: changed from 8000 to 8443 to match config - Rewrite README.md to reflect current features and usage - Add AGENTS.md and .agents/summary/ documentation for AI assistants
3.7 KiB
3.7 KiB
Workflows
Application Startup
flowchart TD
START[Application Start] --> PARSE[Parse CLI flags]
PARSE --> LOAD[Load config.yaml]
LOAD -->|Error| FATAL[log.Fatal - exit]
LOAD -->|Success| CREATE[Create Hub]
CREATE --> RUN[Start Hub.Run goroutine]
RUN --> METRICS{Metrics enabled?}
METRICS -->|Yes| METSRV[Start metrics server goroutine on :9090]
METRICS -->|No| SKIP[Skip metrics]
METSRV --> TLS{TLS enabled?}
SKIP --> TLS
TLS -->|Yes| TLSSERVE[ListenAndServeTLS on :8443]
TLS -->|No| HTTPSERVE[ListenAndServe on :8443]
Client Connection Workflow
sequenceDiagram
participant Client
participant HTTP as HTTP Server
participant Upgrader as WebSocket Upgrader
participant Hub as Hub.Run()
participant Metrics
Client->>HTTP: GET / (Upgrade: websocket)
HTTP->>Upgrader: CheckOrigin (always true)
Upgrader->>HTTP: Upgrade response
HTTP->>Hub: register <- conn
Hub->>Metrics: ConnectedClients.Set(n)
Hub->>Metrics: ConnectionsTotal.Inc()
Note over HTTP: Spawn reader goroutine
loop Message Loop
Client->>HTTP: WebSocket frame
HTTP->>Hub: broadcast <- message
Hub->>Metrics: MessagesTotal.Inc()
Hub->>Client: WriteMessage to all clients
end
Note over HTTP: Read error or client disconnect
HTTP->>Hub: unregister <- conn
Hub->>Metrics: ConnectedClients.Set(n-1)
Hub->>Metrics: DisconnectionsTotal.Inc()
Hub->>Hub: Close connection, remove from map
Build and Release Workflow
flowchart LR
subgraph Development
CODE[Write Code] --> PUSH[Push to main/develop]
end
subgraph "CI Pipeline"
PUSH --> TEST[go test -v ./...]
PUSH --> LINT[golangci-lint]
TEST --> BUILD[make build]
end
subgraph "Release Pipeline"
TAG[Push v* tag] --> REL_BUILD[Cross-compile]
REL_BUILD --> LINUX[linux/amd64 binary]
REL_BUILD --> MACOS[darwin/arm64 binary]
LINUX --> RELEASE[Gitea Release]
MACOS --> RELEASE
end
Development Workflow
flowchart TD
START[Clone repo] --> DEPS[make deps / go mod tidy]
DEPS --> CONFIG[Edit config.yaml]
CONFIG --> RUN[make run]
RUN --> TEST_LOCAL[Test with example/index.html]
TEST_LOCAL --> WRITE[Write code changes]
WRITE --> UNIT[make test]
UNIT -->|Pass| COMMIT[git commit]
UNIT -->|Fail| WRITE
COMMIT --> PUSH[git push]
PUSH --> CI[CI runs tests + lint]
Message Broadcast Workflow
flowchart TD
MSG[Client sends message] --> CHAN[broadcast channel receives []byte]
CHAN --> INC[MessagesTotal.Inc]
INC --> LOCK[RLock clients map]
LOCK --> ITER{For each client}
ITER -->|Next client| WRITE[WriteMessage]
WRITE -->|Success| ITER
WRITE -->|Error| REMOVE[Remove client, close conn]
REMOVE --> ITER
ITER -->|Done| UNLOCK[RUnlock]
Error Handling Workflows
Connection Upgrade Failure
flowchart LR
REQ[HTTP Request] --> UPG{Upgrade succeeds?}
UPG -->|No| LOG[Log error]
LOG --> RETURN[Return - no cleanup needed]
UPG -->|Yes| REGISTER[Continue with registration]
Write Error During Broadcast
flowchart LR
WRITE[WriteMessage] --> ERR{Error?}
ERR -->|No| NEXT[Continue to next client]
ERR -->|Yes| DEL[Delete from clients map]
DEL --> CLOSE[Close connection]
CLOSE --> NEXT
Note: Write errors during broadcast silently remove the failing client without triggering the unregister channel. This is a potential inconsistency — the
DisconnectionsTotalmetric won't be incremented andConnectedClientsgauge won't be updated for these removals.