Documentation
¶
Overview ¶
Package app wires the WaveHouse process. New builds every component from the boot config and the settings directory, Run drives the long-lived ones under one errgroup until the context is cancelled or one of them fails, and Close releases what New opened, in reverse order. A stop is three bounded phases, and their budgets add rather than multiply: Run drains the in-flight request/response work and ingest batches within server.shutdown_timeout (open SSE streams end at once — they are connections to close, not work to finish), then Close releases the stores under the context its caller passes (ReleaseTimeout), then flushes telemetry under a short budget of its own so the flush that reports on the stop is never starved by a slow close. cmd/wavehouse is the argv/signal/exit-code shell around it; tests/integration builds the same wiring against a ClickHouse testcontainer.
Each component is wired in one place, as one component value: what New opens, what Run loops, and what Close releases. The settings registry is handed whole to each component's wiring function, which derives the per-call getters the internal packages take: keyed by the request's store for the handlers, by tenant id for the async paths (perTenant), and fixed to the default tenant for the ops gate of a flat directory (defaultPolicy).
Index ¶
Constants ¶
const ( // ReleaseTimeout bounds Close's release of the stores. A fixed budget // rather than server.shutdown_timeout: only the drain scales with the // deployment's workload, so the stop's worst case is shutdown_timeout // plus these constants, not a multiple of it. ReleaseTimeout = 5 * time.Second )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the wired process. Construct with New; the zero value is unusable.
func New ¶
New wires every component. ctx bounds construction only — the boot-time schema refresh and the opening of each served tenant's queue; the loops start in Run. A failure releases whatever was already opened and returns the error, so the caller never holds a half-built App.
func (*App) Close ¶
Close releases every resource New opened, newest first, and reports every failure joined. ctx is the release budget (ReleaseTimeout from main), and it is a real bound: a remote implementation's close gives up at the deadline itself, and a close that ignores the context — the local stores (Pebble, ristretto, embedded NATS), which normally finish in milliseconds — is abandoned at it, and the components below it are not released at all (a close started then would overlap the abandoned one and break the reverse order), since the process is exiting either way and the flush that follows reports both. The telemetry flush then runs on its own flushTimeout, so it is never handed a budget a slow close has already spent. Safe to call more than once.
func (*App) Handler ¶
Handler is the router this process serves — the API's, or the ops-only one without the api role — for a harness that serves it itself.
func (*App) Registry ¶
func (a *App) Registry() *discovery.SchemaRegistry
Registry is the default tenant's schema registry, for a harness that refreshes it after creating tables; nil over a nested directory serving no tenant 0, and in a process without the api role.
type BuildInfo ¶
BuildInfo is the ldflags-stamped identity of the binary, served by /version and attached to every OTLP log record.
type Options ¶
type Options struct {
// Config is the boot config, already validated by config.Load.
Config *config.Config
// Build stamps /version and the OTLP logger.
Build BuildInfo
// LogLevel is the process log level; the OTLP-aware logger that replaces
// the default one when otel logs are enabled shares it, so WH_LOG_LEVEL
// keeps applying. Nil means Info.
LogLevel *slog.LevelVar
// Listener, when set, is what Run serves the API on instead of binding
// server.port — a harness's 127.0.0.1:0.
Listener net.Listener
}
Options is what New needs beyond the settings directory itself.