From 96167648994266a78103f6746a11c53795c34ae4 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 12 May 2026 11:10:43 -0400 Subject: [PATCH] updated documentation --- CONFIG.md | 12 ++++-------- EXTEND.md | 9 +++------ README.md | 6 ++++-- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/CONFIG.md b/CONFIG.md index 2d5a854..99a17ab 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -18,6 +18,9 @@ Sets a per-message write deadline. Applied before every call to `WriteMessage`. **`WithCloseHandler(func(code int, text string) error)`** Installs a close handler on the underlying socket. Called when the remote peer sends a close frame. +**`WithRequestHeader(http.Header)`** +Sets custom HTTP headers to be sent during the WebSocket handshake. The default includes `User-Agent: honeybee/0.1.0`. + ### Ping **`WithPingInterval(duration)`** @@ -70,9 +73,6 @@ Sets the capacity of the pool's shared inbox channel. Must be at least 1. **`WithInboundEventsBufferSize(int)`** Sets the capacity of the pool's events channel. Must be at least 1. -**`WithInboundErrorsBufferSize(int)`** -Sets the capacity of the pool's errors channel. Must be at least 1. - **`WithInboundPoolLoggingEnabled(bool)`** Enables or disables pool-level logging. @@ -118,9 +118,6 @@ Sets the capacity of the pool's shared inbox channel. Must be at least 1. **`WithOutboundEventsBufferSize(int)`** Sets the capacity of the pool's events channel. Must be at least 1. -**`WithOutboundErrorsBufferSize(int)`** -Sets the capacity of the pool's errors channel. Must be at least 1. - **`WithOutboundPoolLoggingEnabled(bool)`** Enables or disables pool-level logging. @@ -162,6 +159,7 @@ Replaces the default worker constructor. See [EXTEND.md](EXTEND.md) for the fact | Scope | Setting | Default | Disabled by | Notes | |---|---|---|---|---| | Connection | `WriteTimeout` | 30s | `0` | Per-message write deadline | +| Connection | `RequestHeader` | User-Agent | — | honeybee/0.1.0 | | Connection | `PingInterval` | 20s | `0` | ±10% jitter applied per interval | | Connection | `IncomingBufferSize` | 100 | — | Must be positive | | Connection | `ErrorsBufferSize` | 10 | — | Must be positive | @@ -174,7 +172,6 @@ Replaces the default worker constructor. See [EXTEND.md](EXTEND.md) for the fact | Retry | `JitterFactor` | 0.2 | `0.0` | Range [0.0, 1.0] | | Inbound pool | `InboxBufferSize` | 256 | — | Must be positive | | Inbound pool | `EventsBufferSize` | 10 | — | Must be positive | -| Inbound pool | `ErrorsBufferSize` | 10 | — | Must be positive | | Inbound pool | `LoggingEnabled` | true | `false` | | | Inbound pool | `LogLevel` | nil | — | | | Inbound worker | `InactivityTimeout` | 0 | `0` | 0 disables watchdog | @@ -183,7 +180,6 @@ Replaces the default worker constructor. See [EXTEND.md](EXTEND.md) for the fact | Inbound worker | `LogLevel` | nil | — | | | Outbound pool | `InboxBufferSize` | 256 | — | Must be positive | | Outbound pool | `EventsBufferSize` | 10 | — | Must be positive | -| Outbound pool | `ErrorsBufferSize` | 10 | — | Must be positive | | Outbound pool | `LoggingEnabled` | true | `false` | | | Outbound pool | `LogLevel` | nil | — | | | Outbound worker | `KeepaliveTimeout` | 60s | `0` | 0 disables keepalive | diff --git a/EXTEND.md b/EXTEND.md index 71644d6..1d41872 100644 --- a/EXTEND.md +++ b/EXTEND.md @@ -33,7 +33,6 @@ The pool constructs a `PoolPlugin` and passes it to `Start`. It gives the worker type PoolPlugin struct { Inbox chan<- InboxMessage Events chan<- PoolEvent - Errors chan<- error InboxCounter *atomic.Uint64 OnExit OnExitFunction // inbound only Handler slog.Handler @@ -42,9 +41,7 @@ type PoolPlugin struct { **`Inbox`** The shared channel that delivers received messages to the pool's consumer. All peers in the pool deliver to the same inbox channel. Workers must include their peer ID in each `InboxMessage`. -**`Events`** The shared channel for lifecycle events. Outbound workers emit `EventConnected` and `EventDisconnected` directly. Inbound workers do not touch this channel directly; instead they call `OnExit`, and the pool translates the exit kind into the appropriate event. - -**`Errors`** The shared channel for non-fatal errors, such as dial failures on an outbound worker. Errors sent here do not stop the pool. +**`Events`** The shared channel for lifecycle events. Outbound workers emit `EventConnected` and `EventDisconnected` directly. Inbound workers do not touch this channel directly; instead they call `OnExit`, and the pool translates the exit kind into the appropriate event. All events include a timestamp in the `At` field. **`InboxCounter`** An atomic counter owned by the pool. Workers must increment this once for each message forwarded to `Inbox`. The pool reads it in `Stats()`. @@ -78,7 +75,7 @@ The default inbound worker is assembled from these exported functions. Each can **`RunHeartbeatForwarder(ctx, conn, heartbeat, logger)`** Reads from `conn.Heartbeat()` and forwards each signal to `heartbeat`. This propagates pong replies from the connection layer into the worker's heartbeat channel, so pongs reset the inactivity watchdog alongside data messages. -**`RunQueue(id, ctx, in, out, maxQueueSize, droppedCount)`** Buffers messages between the reader and the forwarder. When `maxQueueSize` is positive and the queue is full, the oldest message is dropped and `droppedCount` is incremented. When `maxQueueSize` is zero, the queue grows without bound. +**`RunQueue(id, ctx, in, out, maxQueueSize, droppedCount, bufferDepth)`** Buffers messages between the reader and the forwarder. When `maxQueueSize` is positive and the queue is full, the oldest message is dropped and `droppedCount` is incremented. When `maxQueueSize` is zero, the queue grows without bound. `bufferDepth` is an `*atomic.Int64` maintained as the current number of items in the queue. **`RunForwarder(id, ctx, messages, inbox, workerProcessedCount, poolInboxCount)`** Reads from `messages` and writes to `inbox`. Increments both counters on each successful delivery. @@ -110,7 +107,7 @@ The factory is set via `WithOutboundWorkerFactory` on the pool config. ### Building Blocks -**`RunDialer(id, ctx, pool, dial, newConn, logger)`** Listens on `dial` for connection requests. On each signal, calls `connect` to dial a new `*transport.Connection`. While a dial is in progress, drains additional `dial` signals so that at most one dial runs at a time. On failure, sends the error to `pool.Errors` and waits for the next `dial` signal. On success, sends the connection on `newConn`. Exits when `ctx` is cancelled. +**`RunDialer(id, ctx, pool, dial, newConn, logger)`** Listens on `dial` for connection requests. On each signal, calls `connect` to dial a new `*transport.Connection`. While a dial is in progress, drains additional `dial` signals so that at most one dial runs at a time. On failure, logs the error and waits for the next `dial` signal. On success, sends the connection on `newConn`. Exits when `ctx` is cancelled. **`RunKeepalive(ctx, heartbeat, keepalive, timeout, logger)`** Monitors `heartbeat`. Resets a timer on each signal. When the timer fires, sends a signal on `keepalive` to notify the session that the connection should be replaced. When `timeout` is zero, keepalive is disabled: it drains `heartbeat` without acting and exits when `ctx` is cancelled. diff --git a/README.md b/README.md index 0cc55f0..31a27a6 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ go func() { // React to peer lifecycle: go func() { for ev := range pool.Events() { + // ev.At is the event timestamp switch ev.Kind { case honeybee.InboundEventDisconnected: // clean close case honeybee.InboundEventDroppedClose: // peer closed with abnormal code @@ -176,6 +177,7 @@ go func() { go func() { for ev := range pool.Events() { + // ev.At is the event timestamp switch ev.Kind { case honeybee.OutboundEventConnected: case honeybee.OutboundEventDisconnected: @@ -196,7 +198,7 @@ After a disconnect, the worker waits for `ReconnectDelay` before attempting the `Send` returns `ErrConnectionUnavailable` during the gap between a disconnect and the next successful reconnect. Callers should wait for `OutboundEventConnected` before retrying and maintain their own write buffers if needed. -Dial failures surface on `pool.Errors()`. These do not stop the pool; it continues retrying according to the connection's retry config. +Dial failures are handled internally by the worker's retry logic and documented in structured logs. These do not stop the pool; it continues retrying according to the connection's retry config. ## Ping-Pong Heartbeats @@ -223,7 +225,7 @@ stats := pool.Stats() // Single peer peerStats, err := pool.PeerStats(peerID) -// peerStats.Worker — queue depths, processed/dropped/sent counts +// peerStats.Worker — queue depths, buffer depth, processed/dropped/sent counts // peerStats.Connection — channel depths, receive/send/heartbeat counts (inbound) // Bare connection