Documentation
¶
Overview ¶
Package config loads application configuration from environment variables. All configuration is immutable after initialization.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// DBPath is the path to the SQLite database file.
DBPath string
// PeeringDBBaseURL is the base URL for the PeeringDB API.
PeeringDBBaseURL string
// SyncToken is the shared secret for on-demand sync trigger authentication.
SyncToken string
// SyncInterval is the duration between automatic sync runs.
SyncInterval time.Duration
// ListenAddr is the address the HTTP server binds to.
ListenAddr string
// CORSOrigins is a comma-separated list of allowed CORS origins.
// Configured via PDBPLUS_CORS_ORIGINS. Default is "*".
CORSOrigins string
// DrainTimeout is the graceful shutdown drain timeout.
// Configured via PDBPLUS_DRAIN_TIMEOUT. Default is 10 seconds.
DrainTimeout time.Duration
// OTelSampleRate is the trace sampling ratio (0.0 to 1.0).
// Configured via PDBPLUS_OTEL_SAMPLE_RATE. Default is 1.0 (always sample).
OTelSampleRate float64
// OTelSQL enables per-query OpenTelemetry DB spans (XSAM/otelsql) on the
// shared *sql.DB. Configured via PDBPLUS_OTEL_SQL. Default true — the data
// is useful and its volume is bounded by the trace sampler; set
// PDBPLUS_OTEL_SQL=false to disable. Scheduled sync cycles are never traced
// regardless (the prior high-volume concern); only a manually-triggered
// POST /sync is — see internal/otel sampler.
OTelSQL bool
// SyncStaleThreshold is the maximum age of sync data before health reports degraded.
// Configured via PDBPLUS_SYNC_STALE_THRESHOLD. Default is 24h.
SyncStaleThreshold time.Duration
// SyncMode controls whether sync uses full re-fetch or incremental delta fetch.
// Configured via PDBPLUS_SYNC_MODE. Default is "incremental" (flipped
// 2026-04-26 — upstream ?since= empirically confirmed to emit status='deleted'
// tombstones for converged deletion semantics). 'full' remains an explicit
// operator override for first-sync, recovery, and escape-hatch use.
SyncMode SyncMode
// PublicTier is the resolved visibility tier for anonymous HTTP callers.
// Configured via PDBPLUS_PUBLIC_TIER. Default TierPublic admits only
// visible="Public" rows. Setting PDBPLUS_PUBLIC_TIER=users elevates
// anonymous callers to TierUsers for private-instance deployments.
// Parsed case-sensitive lowercase only; any other value is a
// fail-fast startup error.
PublicTier privctx.Tier
// PeeringDBAPIKey is the optional PeeringDB API key for authenticated access.
// Configured via PDBPLUS_PEERINGDB_API_KEY. Empty string means unauthenticated.
PeeringDBAPIKey string
// StreamTimeout is the maximum duration for a single streaming RPC.
// Configured via PDBPLUS_STREAM_TIMEOUT. Default is 60 seconds.
StreamTimeout time.Duration
// CSPEnforce controls whether the CSP middleware serves the enforcing
// Content-Security-Policy header (true) or the Content-Security-Policy-Report-Only
// header (false). Configured via PDBPLUS_CSP_ENFORCE. Default is false —
// enforcement is opt-in per deploy through v1.13.
CSPEnforce bool
// SyncMemoryLimit is the peak Go heap ceiling (bytes) checked after
// the sync worker's Phase A fetch pass completes and before the
// database transaction opens. If runtime.ReadMemStats reports
// HeapAlloc above this value, the sync aborts with a WARN log and
// returns sync.ErrSyncMemoryLimitExceeded. The next scheduled sync
// retries normally after the current batches are reclaimed by GC.
//
// Configured via PDBPLUS_SYNC_MEMORY_LIMIT. Default is 400MB —
// matches the regression gate in BenchmarkSyncWorker_FullMemoryPeak
// and leaves 112 MB headroom under the 512 MB Fly.io VM cap per
// v1.13 hard constraint. Set to 0 to disable the guardrail (local
// dev only; guardrail is defense-in-depth against runtime memory
// spikes that exceed what the benchmark harness measured).
//
// Unit suffix is required (KB/MB/GB/TB, base 1024); bare numbers
// are rejected for unambiguous operator configuration.
SyncMemoryLimit int64
// ResponseMemoryLimit is the per-response memory budget in bytes.
// Before streaming a pdbcompat list response, the handler runs a
// pre-flight SELECT COUNT(*) and multiplies by a conservative
// per-row byte estimate; if the product exceeds this budget, the
// request is rejected with an RFC 9457 413 problem-detail BEFORE
// any row data is materialised.
//
// Configured via PDBPLUS_RESPONSE_MEMORY_LIMIT. Default is 128 MiB
// (134217728 bytes) — sized against the 256 MB replica total minus
// an 80 MB Go runtime baseline and 48 MB slack for other in-flight
// requests + GC overhead. Unit suffix is REQUIRED (KB/MB/GB/TB,
// base 1024); bare numbers are rejected.
// Set to 0 to disable the check (local dev only; the guardrail is
// the reason exposing limit=0 is safe in prod).
ResponseMemoryLimit int64
// HeapWarnBytes is the peak Go heap threshold (bytes) above which the
// sync worker emits slog.Warn("heap threshold crossed", ...) at the
// end of each sync cycle. The OTel span attribute
// pdbplus.sync.peak_heap_bytes is emitted regardless; only the Warn
// is threshold-gated. Configured via PDBPLUS_HEAP_WARN_MIB (integer
// MiB, no unit suffix — env var name retained for compatibility).
// Default 400 MiB matches the Fly 512 MB VM cap minus a 112 MB
// safety margin. Zero disables the warn (attr still emitted
// so dashboards retain timeseries).
//
// A sustained breach across multiple cycles is the operational
// signal to re-evaluate whether PDBPLUS_SYNC_MODE=incremental is
// keeping memory pressure within bounds.
HeapWarnBytes int64
// RSSWarnBytes is the peak OS RSS threshold (bytes) above which the
// sync worker emits slog.Warn at the end of each sync cycle. Read from
// /proc/self/status VmHWM on Linux; skipped on other OSes (the RSS
// attr is then omitted — it is not set to zero). Configured via
// PDBPLUS_RSS_WARN_MIB (integer MiB, no unit suffix). Default 384 MiB.
// Zero disables the warn.
RSSWarnBytes int64
// PeeringDBRPS is the unauthenticated sustained requests-per-second
// cap to the PeeringDB API. Configured via PDBPLUS_PEERINGDB_RPS
// (float, must be >0). Default 2.0. Burst is hardcoded at 1 in the
// peeringdb client. Authenticated requests (PDBPLUS_PEERINGDB_API_KEY
// set) override this to 60 req/min — the upstream auth quota is fixed
// regardless of operator preference.
PeeringDBRPS float64
// FKBackfillMaxRequestsPerCycle caps the number of underlying HTTP
// requests issued by FK-backfill per sync cycle. Configured via
// PDBPLUS_FK_BACKFILL_MAX_REQUESTS_PER_CYCLE (non-negative integer).
// Default 20 — at 1 req/sec authenticated, that's ≈20s of upstream
// pressure per cycle, well within budget. Set to 0 to disable
// backfill entirely (drop-on-miss behavior).
//
// Semantic shift (v1.18.5): the previous cap counted
// rows. With the dataloader pattern (one ?id__in= request per up to
// FetchByIDsBatchSize rows), counting rows is a weak circuit
// breaker — a 200-row backfill is 2 HTTP requests, not 200, and
// upstream's API_THROTTLE_REPEATED_REQUEST cares about request
// count, not row count. The cap now directly bounds the surface
// it's meant to protect.
FKBackfillMaxRequestsPerCycle int
// FKBackfillTimeout is the per-cycle wall-clock budget for FK
// backfill HTTP activity. v1.18.3: backfill calls happen inside the
// sync transaction; without a deadline a cascade of slow / rate-
// limited backfills could hold the tx open for tens of minutes,
// stalling LiteFS replication. After the deadline, fkBackfillParent
// short-circuits to drop-on-miss so the rest of the sync (bulk
// fetches + upserts) commits cleanly and the next cycle picks up
// where we left off. Configured via PDBPLUS_FK_BACKFILL_TIMEOUT
// (Go duration). Default 5m. Zero or negative disables the deadline
// (only the cap applies).
FKBackfillTimeout time.Duration
// SyncTimeout bounds the wall clock of a single sync attempt (each
// retry inside SyncWithRetry gets its own budget). The upstream HTTP
// client deliberately carries no whole-request timeout (a full-sync
// body read is legitimately slow), so without this deadline a body
// that trickles bytes forever would wedge the cycle — and the
// worker's running latch — for the life of the process, silently
// freezing sync fleet-wide. Configured via PDBPLUS_SYNC_TIMEOUT
// (Go duration). Default 30m. Zero disables (dev/debug only).
SyncTimeout time.Duration
// FullSyncInterval is the interval after which sync cycles force a
// full bare-list refetch — escape hatch against pathological upstream
// cross-row inconsistency in any since= design (a response with row
// R' (updated=M) present but earlier row R (updated < M) missing →
// R is permanently missed without periodic full refetch). Configured
// via PDBPLUS_FULL_SYNC_INTERVAL (Go duration). Default 24h. Zero
// disables the escape hatch (only the per-cycle MAX(updated) cursor
// applies).
FullSyncInterval time.Duration
}
Config holds all application configuration. Immutable after Load returns.
Click to show internal directories.
Click to hide internal directories.