Files
Claude 6d91fd9c36 Add streaming brotli compression and hot-reloadable config (livevue.toml)
Key changes:

- **src/config.rs** – `LiveVueConfig` (server host/port, brotli quality +
  window size), loaded from `livevue.toml`. A notify-based file watcher
  reloads the config on any file change; a SIGHUP handler does the same on
  demand. Falls back to compiled-in defaults when the file is absent.

- **src/brotli_layer.rs** – `BrotliBody`, a custom `http_body::Body` wrapper
  that streams brotli-compressed data through a single persistent
  `brotli::CompressorWriter`. The encoder survives across SSE event flushes,
  so its sliding window accumulates context from all prior events —
  progressively better compression as the stream grows. Both quality (0–11)
  and window size (lgwin 10–24, i.e. 1 KB – 16 MB) are taken from config.
  `brotli_compression` is an axum `from_fn_with_state` middleware that
  activates only when the client sends `Accept-Encoding: br`.

- **src/server.rs** – `AppState` gains a `config: SharedConfig` field.
  `AppState::new` takes the config; `AppState::new_default` is a zero-config
  convenience constructor.

- **livevue.toml** – documented example config with inline comments
  explaining each field and the brotli window-size tradeoff table.

- **examples/todo** – loads config via `load_and_watch_config`, derives the
  bind address from `config.server`, and applies `brotli_compression` as a
  router layer.

https://claude.ai/code/session_01UnQQkkwts64FPUsSzFfdQb
2026-03-12 07:06:10 +00:00

69 lines
2.6 KiB
TOML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# livevue.toml — livevue-rs server configuration
#
# This file is optional. The server starts with compiled-in defaults when it
# is absent. When present, it is loaded on startup and then watched for
# changes automatically (inotify on Linux, kqueue on macOS, FSEvents on macOS).
#
# To force a reload without restarting: kill -HUP <pid>
#
# Note: [server] changes (host / port) require a full restart because the TCP
# listener is bound once at startup. All brotli settings apply to new
# connections immediately after a reload.
# ---------------------------------------------------------------------------
# HTTP server
# ---------------------------------------------------------------------------
[server]
# Address to bind. "0.0.0.0" listens on all interfaces.
host = "0.0.0.0"
# TCP port.
port = 3000
# ---------------------------------------------------------------------------
# Brotli streaming compression
# ---------------------------------------------------------------------------
#
# Brotli is the compression algorithm of choice for Datastar SSE streams.
# Unlike gzip (which compresses each HTTP response independently), brotli
# maintains a *sliding window* across the entire SSE byte stream. All events
# on a connection share a single encoder context, so later events — which
# often contain similar HTML structure — get compressed with reference to
# everything that was sent earlier. Compression ratios improve progressively
# over the lifetime of a long-lived connection.
#
# The browser sends "Accept-Encoding: br" if it supports brotli. The
# middleware checks this and only activates compression for those clients.
[brotli]
# Set to false to disable brotli and send SSE events uncompressed.
enabled = true
# Encoder quality: 0 (fastest, worst ratio) … 11 (slowest, best ratio).
#
# For real-time SSE, 46 gives a good latency/ratio tradeoff. Values above 9
# incur significant CPU cost with diminishing returns for typical HTML
# payloads. Default: 5.
quality = 5
# Sliding window size as log₂ of bytes (brotli's `lgwin` parameter).
#
# The window is how much previously compressed data the encoder can
# reference. Larger ⇒ better compression, more memory per connection.
#
# lgwin │ Window size
# ──────┼────────────
# 10 │ 1 KB
# 16 │ 64 KB
# 20 │ 1 MB
# 22 │ 4 MB ← default
# 24 │ 16 MB
#
# For a server with many concurrent SSE connections, consider whether the
# memory cost (window_size bytes × number of connections) is acceptable.
# Reduce to 20 or 16 under memory pressure.
window_size = 22