config

package
v1.23.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: BSD-3-Clause Imports: 11 Imported by: 0

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.

func Load

func Load() (*Config, error)

Load reads configuration from environment variables, applies defaults, validates required fields, and returns an immutable Config. It fails fast on invalid configuration.

type SyncMode added in v1.2.0

type SyncMode string

SyncMode controls the sync strategy.

const (
	// SyncModeFull performs a complete re-fetch of all objects.
	SyncModeFull SyncMode = "full"
	// SyncModeIncremental fetches only objects modified since the last sync.
	SyncModeIncremental SyncMode = "incremental"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL