Documentation
¶
Overview ¶
Package server contains the HTTP server lifecycle, the first-run detector that bootstraps an admin user, and the boot banner.
Thumbnail backfill — walks every persisted file node and dispatches the thumbnail pipeline so existing instances catch up after deps are added or after the cache is rebuilt.
Used by:
- `filex thumb backfill` CLI subcommand (synchronous, prints progress)
- FILEX_THUMB_BACKFILL_ON_BOOT=once (background, fired from Start())
Both routes share BackfillThumbs to keep the dispatch logic in one place.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotIndexed = errors.New("thumb backfill: storage catalogue not ready")
ErrNotIndexed is returned (wrapped, after every other storage has been processed) when at least one targeted storage's catalogue cannot be trusted to hold its files.
⚠⚠ Why a backfill refuses instead of doing what it can. A backfill renders thumbnails for NODES — rows in the catalogue — because that is what a thumbnail is keyed on. Files written straight onto a storage's backend have no node until a sync writes one, and a sync answers 202 and writes them in the background. So this command, run against a storage nobody had synced, or one whose sync was still going, walked an empty (or half-written) catalogue and printed `{processed: 0, ok: 0, failed: 0, skipped: 0}` with exit 0. Measured 2026-09-14, and it is how a screenshot run produced a grid with no thumbnails while every step it took said "ok". A command that does nothing and reports success is worse than one that fails: nobody goes looking.
It cannot simply sync first: the CLI runs beside a live server, and two processes syncing one storage into one database is its own bug. So it says what is missing and what to do, and exits non-zero.
Functions ¶
func PrintBanner ¶
func PrintBanner(w io.Writer, cfg config.Config, fr FirstRunCredentials, caps map[string]model.ExternalServiceState, storages []*model.Storage)
PrintBanner writes the first-run banner to w (typically os.Stdout).
fr is the FirstRun result — when non-empty it adds the "first run detected" credentials section.
Types ¶
type BackfillOptions ¶
type BackfillOptions struct {
// StorageIDs, when non-empty, restricts the run to specific storages.
// Empty means "every enabled storage".
StorageIDs []int64
// Limit caps the number of files processed across all storages
// combined. 0 = unlimited.
Limit int
// RetryFailed includes nodes whose existing thumbnails row is in
// state="failed". Without this, failed rows are skipped (so a flaky
// office doc doesn't block every subsequent run).
RetryFailed bool
// RetrySkipped includes nodes whose existing thumbnails row is in
// state="skipped". Use when the pipeline has gained coverage for
// kinds that previously skipped (e.g. v0.1.7 generic fallback /
// audio waveform) — without this, old rows freeze the pipeline.
RetrySkipped bool
// Concurrency controls the worker pool size. <=0 → 4.
Concurrency int
// ProgressEvery determines how many processed nodes between an
// OnProgress callback. <=0 disables intermediate notifications.
ProgressEvery int
// OnProgress, if non-nil, is invoked with the running counters every
// ProgressEvery files. CLI uses this to print to stdout; the boot
// goroutine leaves it nil and lets the slog summary do the work.
OnProgress func(BackfillStats)
}
BackfillOptions tunes a backfill run.
type BackfillStats ¶
type BackfillStats struct {
Processed int
OK int
Failed int
Skipped int
// NotIndexed names the storages this run REFUSED, and why. See
// ErrNotIndexed.
NotIndexed []NotIndexedStorage
}
BackfillStats is the counter snapshot emitted via OnProgress and returned from BackfillThumbs.
type FirstRunCredentials ¶
type FirstRunCredentials struct {
AdminEmail string
AdminPassword string // plaintext — only ever shown ONCE (blank when preset)
WroteFile string // path of ~/.filex/.first-run.txt (blank when preset)
// Preset is true when the admin was created from FILEX_ADMIN_EMAIL /
// FILEX_ADMIN_PASSWORD — the operator already knows the password, so it is
// neither written to disk nor echoed in the banner.
Preset bool
}
FirstRunCredentials is what FirstRun returns when bootstrapping. Empty AdminEmail means no first-run was needed (a user already exists).
func FirstRun ¶
func FirstRun(ctx context.Context, store db.Store, dataDir, adminEmail, adminPassword string) (FirstRunCredentials, error)
FirstRun checks whether the users table is empty. If so it creates an admin user and records the timestamp in the settings table.
When adminEmail/adminPassword are supplied (from FILEX_ADMIN_* env) they are used as-is and nothing is written to disk. Otherwise it falls back to admin@local with a fresh random password written to a 0600 file at {dataDir}/.first-run.txt.
Returns zero-value FirstRunCredentials when no bootstrap was performed.
type NotIndexedStorage ¶
NotIndexedStorage is one storage a backfill would have reported success on while rendering nothing for it.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the high-level wrapper around HTTP + workers.
func (*Server) BackfillThumbs ¶
func (s *Server) BackfillThumbs(ctx context.Context, opts BackfillOptions) (BackfillStats, error)
BackfillThumbs walks every file node in scope and (re)dispatches the thumbnail pipeline. Safe to call concurrently with normal operation — the pipeline itself is idempotent and uses UpsertThumbnail.