From 716b18f69d5116a2ff9465e2ba439fe748358172 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 19 Feb 2026 16:52:46 +0000 Subject: [PATCH] Delete page "Process-Streaming.-" --- Process-Streaming.-.md | 136 ----------------------------------------- 1 file changed, 136 deletions(-) delete mode 100644 Process-Streaming.-.md diff --git a/Process-Streaming.-.md b/Process-Streaming.-.md deleted file mode 100644 index 36436e1..0000000 --- a/Process-Streaming.-.md +++ /dev/null @@ -1,136 +0,0 @@ -# Process Streaming - -The `go-ws` package provides two convenience methods for streaming process output and status updates over WebSocket channels. These are the primary integration point between a process manager and connected web frontends. - -## SendProcessOutput - -Streams a single line of process output to all clients subscribed to the `process:{id}` channel. - -```go -func (h *Hub) SendProcessOutput(processID string, output string) error -``` - -**Parameters:** -- `processID` -- unique identifier for the process (e.g. `"web-server-1"`) -- `output` -- a single line of stdout/stderr output - -**Wire format:** - -```json -{ - "type": "process_output", - "channel": "process:web-server-1", - "processId": "web-server-1", - "data": "2026-02-19 10:00:00 Listening on :8080", - "timestamp": "2026-02-19T10:00:00.123Z" -} -``` - -**Example -- forwarding output from an exec.Cmd:** - -```go -scanner := bufio.NewScanner(cmd.Stdout) -for scanner.Scan() { - hub.SendProcessOutput("web-server-1", scanner.Text()) -} -``` - -## SendProcessStatus - -Sends a process lifecycle status change to all clients subscribed to the `process:{id}` channel. - -```go -func (h *Hub) SendProcessStatus(processID string, status string, exitCode int) error -``` - -**Parameters:** -- `processID` -- unique identifier for the process -- `status` -- status string (e.g. `"running"`, `"exited"`, `"crashed"`, `"stopped"`) -- `exitCode` -- the process exit code (0 for success, non-zero for failure; use 0 for non-exit statuses like `"running"`) - -**Wire format:** - -```json -{ - "type": "process_status", - "channel": "process:proc-1", - "processId": "proc-1", - "data": { - "status": "exited", - "exitCode": 0 - }, - "timestamp": "2026-02-19T10:05:00.456Z" -} -``` - -## Integration with Core Framework - -The hub integrates with the Core framework's action/message-passing system. Process managers dispatch actions, and a registered action handler forwards them to the WebSocket hub: - -```go -core.RegisterAction(func(c *framework.Core, msg framework.Message) error { - switch m := msg.(type) { - case process.ActionProcessOutput: - hub.SendProcessOutput(m.ID, m.Line) - case process.ActionProcessExited: - hub.SendProcessStatus(m.ID, "exited", m.ExitCode) - case process.ActionProcessStarted: - hub.SendProcessStatus(m.ID, "running", 0) - } - return nil -}) -``` - -This decouples process management from WebSocket delivery. The process manager only needs to emit actions; the WebSocket layer handles fan-out to subscribed clients. - -## Client-Side Consumption - -A JavaScript client subscribes to a process channel and handles the two message types: - -```javascript -const socket = new WebSocket("ws://localhost:8080/ws"); - -const processId = "web-server-1"; - -socket.onopen = () => { - socket.send(JSON.stringify({ - type: "subscribe", - data: "process:" + processId - })); -}; - -socket.onmessage = (event) => { - const msg = JSON.parse(event.data); - - switch (msg.type) { - case "process_output": - terminal.appendLine(msg.data); - break; - case "process_status": - statusBadge.textContent = msg.data.status; - if (msg.data.exitCode !== 0) { - statusBadge.classList.add("error"); - } - break; - } -}; -``` - -## Channel Routing - -Both methods route through `SendToChannel` with the channel name `"process:" + processID`. See [[Channel-Subscriptions]] for details on how channel delivery works. - -If no clients are subscribed to the process channel, the message is silently discarded (no error returned). This means it is safe to call `SendProcessOutput` at high frequency even when no frontends are connected. - -## Backpressure - -If a client's send buffer (capacity 256) is full, that client is skipped for the current message. The message is not queued or retried. For high-throughput process output, this means slow consumers may miss lines. - -The `SendToChannel` path does **not** schedule the client for unregistration when the buffer is full (unlike the `Broadcast` path). The client remains connected and will receive the next message if buffer space is available. - -## Related Pages - -- [[Home]] -- Overview and quick start -- [[Architecture]] -- Hub internals and goroutine model -- [[Message-Types]] -- Wire format and message type constants -- [[Channel-Subscriptions]] -- Channel pub/sub mechanics