Documentation
¶
Overview ¶
Package badgergc provides a small standalone Caddy app module that periodically runs Badger's value-log garbage collection on the *same* in-process *badger.DB handle that Souin's Badger storage already holds open.
Souin (the Caddy HTTP cache, via github.com/caddyserver/cache-handler) stores its cache in a Badger value-log DB. Badger never reclaims dead value-log space on its own — RunValueLogGC has to be called explicitly — so a long-lived cache steadily accumulates garbage vlog files (tens of gigabytes in our case) that never shrink. This module reclaims that space with zero downtime and no fork of Souin.
REACHING THE LIVE HANDLE. darkweak/storages exposes a process-global registry (core.GetRegisteredStorers), but cache-handler DRAINS it: its cache app's Start() calls core.ResetRegisteredStorages() after copying the storers into its own exported field. So the registry is empty at runtime — the live storers live on the cache app itself (httpcache.SouinApp.Storers []types.Storer, whose concrete elements are *badger.Badger, embedding the exported *badger.DB). We therefore reach them through Caddy's app graph: ctx.App("cache") → *httpcache.SouinApp → .Storers → *badger.Badger → .DB. Compiled into the same binary as Souin, these types resolve to the identical types, so we reuse Souin's own handle: no second Open(), no lock fight, and RunValueLogGC (which Badger serializes internally and is designed to run alongside live traffic) does its work with zero contention.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type App ¶
type App struct {
// Interval is how often to run a GC sweep. Default: 10m.
Interval caddy.Duration `json:"interval,omitempty"`
// DiscardRatio is passed to Badger's RunValueLogGC: a value-log file is
// rewritten only if it can discard at least this fraction of its space.
// Must be in (0.0, 1.0). Default: 0.5.
DiscardRatio float64 `json:"discard_ratio,omitempty"`
// MaxRewritesPerSweep caps how many value-log files a single sweep will
// rewrite (across all Badger storers), spreading a large backlog -- e.g. the
// tens of gigabytes reclaimed on the first sweep after deploy -- across
// several ticks instead of one long, I/O-heavy sweep. 0 (default) = no cap.
MaxRewritesPerSweep int `json:"max_rewrites_per_sweep,omitempty"`
// contains filtered or unexported fields
}
App is the badger_gc Caddy app. It runs a single background goroutine that, on a fixed interval, runs Badger value-log GC on every Badger-backed storer the cache app holds, until Badger reports nothing left to reclaim.
func (App) CaddyModule ¶
func (App) CaddyModule() caddy.ModuleInfo
CaddyModule returns the Caddy module information. badger_gc is a top-level app module (not an HTTP handler), so its ID has no dotted namespace prefix.
func (*App) Provision ¶
Provision sets defaults, grabs a logger, and resolves the cache app whose Storers hold the live Badger handle(s).
func (*App) Start ¶
Start launches the background GC goroutine. Attach confirmation and the first reclaim happen inside the goroutine (see run), so Start never blocks Caddy.
func (*App) Stop ¶
Stop signals the sweep goroutine to exit AND waits (bounded) for it to return, so a config reload never leaves the old goroutine running GC on a Badger store the new Souin is closing/reopening. The sweep checks done between value-log rewrites, so the wait is normally near-instant; the timeout only guards a single in-flight file rewrite that cannot be interrupted.