- 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
141 lines
3.7 KiB
Markdown
141 lines
3.7 KiB
Markdown
# Workflows
|
|
|
|
## Application Startup
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
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 `DisconnectionsTotal` metric won't be incremented and `ConnectedClients` gauge won't be updated for these removals.
|