static

package
v0.2.44 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: MPL-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package static serves bundled / workspace files for the txco://static op, layered first-match-wins: a routed stack's own <workspace>/OPS/<stack>/FILES/** , the chassis-wide <workspace>/FILES/** , then the embedded chassis default (favicon.ico).

The set + the bytes are loaded into memory at startup and rebuilt on dbcache reload (see Index). A request NEVER touches the filesystem: Resolve is a pure in-memory radix lookup, so static serving and the boot pipeline that calls it stay off the disk critical path.

Index

Constants

View Source
const (
	MaxIndexFiles = 2048
	MaxIndexBytes = 64 << 20
	MaxIndexDepth = 10
)

Index-build budget across the workspace layers (the embedded default is trusted and always loaded, exempt from these). Bounds the in-memory cache so a runaway FILES/ tree can't exhaust RAM; overflow is logged and skipped (already-indexed files still serve).

View Source
const (
	MarkerDir = "_txco"
)

Markers are files whose PATH is the whole message; their bytes are never read, so a marker works the same on the fleet, where a tenant FILES/ row carries only its content hash. They live under FILES/_txco/, which is private like any "_" path, and never enter a layer's file set, so neither HTTP nor read-file (Asset) sees them.

_txco/public/<root>/_txco_mark       <root> may be served over HTTP
_txco/immutable/<prefix>/_txco_mark  files under <prefix>/ are content-
                                     hashed: cache them for a year

A Web ABI install writes them: a public marker for each "_" root its public/ tree contains, an immutable marker for each prefix its manifest names.

View Source
const MaxFileBytes = 1 << 20

MaxFileBytes caps any single static file. Same 1 MiB ceiling the continuation worker callback uses (server/personality/web/continuation.go). Larger files are skipped at index-build time (never read per request).

Variables

This section is empty.

Functions

func ImmutableMarker added in v0.2.44

func ImmutableMarker(prefix string) string

ImmutableMarker is the FILES/-relative path of the marker that marks every file under prefix immutable.

func PrivateRoot added in v0.2.44

func PrivateRoot(rel string) string

PrivateRoot returns rel cut at the end of its first "_"-prefixed segment ("" when it has none): _app/x.js → _app, assets/_Dk3.js → assets/_Dk3.js, a/_b/_c/d → a/_b. It is the unit a public marker names.

func PublicMarker added in v0.2.44

func PublicMarker(root string) string

PublicMarker is the FILES/-relative path of the marker that makes root (a path cut at its first "_" segment, see PrivateRoot) servable.

Types

type Index

type Index struct {
	// contains filtered or unexported fields
}

Index is the in-memory static set, three layers deep (per routed stack → chassis-wide → embedded). Trees are immutable (github.com/hashicorp/go-immutable-radix); Rebuild builds fresh ones and swaps under mu. Reads snapshot the pointers under mu then use the immutable structures lock-free — the processor.Unit.Mux idiom.

func NewIndex

func NewIndex(root string, log *zap.Logger) *Index

NewIndex builds the index immediately so the chassis serves correctly before the first reload.

func (*Index) Asset added in v0.2.12

func (ix *Index) Asset(tenant, stack, rel string) (Result, bool)

Asset resolves an EXACT stack-relative path across the same layers as Lookup (routed stack → chassis → embedded → tenant CAS) but WITHOUT try_files probing and WITHOUT the `_`-private HTTP filter — so ops (e.g. txco://read-file) can read FILES/_mail/ templates as data. Bytes are inline (Result.Body) or a tenant CAS entry (Result.Hash, the caller resolves via filecas). Returns (_, false) on miss. Pure in-memory: the index holds the bytes, so this never touches the filesystem.

func (*Index) Lookup

func (ix *Index) Lookup(tenant, stack, reqPath string) Result

Lookup resolves a request to a static file, layered first-match-wins, with try_files-style fallback so prerendered routes serve their own HTML for the extension-less URL a browser actually requests:

exact            /assets/x.css → assets/x.css
clean URL        /about        → about.html
directory index  /blog         → blog/index.html
root             /             → index.html

A path whose last segment already has an extension only probes the exact match (so /app.js never tries app.js.html or app.js/index.html). Backward-compatible: a path with no matching file still misses and, if it sits under a static-owned directory, reports Owned (→ 404) so the op answers 404 rather than leaking to app routing; a bare top-level miss passes through. Mirrors nginx try_files / Caddy / the layout adapter-static emits. Pure in-memory; no filesystem access.

Privacy: a path with a "_"-prefixed segment is private (e.g. FILES/_mail/ templates: readable by ops through Asset, never served over HTTP) unless the layer holding it marks that path's root public (FILES/_txco/public/, what a Web ABI install writes for its public/ tree). A private path is a plain miss, never Owned, so its existence doesn't leak.

func (*Index) Rebuild

func (ix *Index) Rebuild()

Rebuild reloads every layer from disk + embed into fresh structures and atomically swaps them in. Called at startup and on dbcache reload — never on the request path.

func (*Index) RebuildTenant added in v0.2.6

func (ix *Index) RebuildTenant(db *sql.DB) error

RebuildTenant reloads the tenant FILES/ metadata layer (path → content hash + size, no bytes) from the runtime DB and atomically swaps it in. Modeled on admission.Rebuild: nil-safe, and it keeps the prior layer on any error so a transient DB hiccup never blanks tenant serving. db is the handle passed by dbcache.OnReload (or dbc.Snapshot() for the initial build) — never capture dbc.Db.

type Result

type Result struct {
	Found bool
	Owned bool
	Body  []byte // set for inline (operator) layers
	// Hash is set for a tenant CAS entry instead of Body: the caller
	// resolves the bytes from the filecas store by this content hash.
	Hash  string
	Size  int64
	Ctype string
	ETag  string
	// Immutable: the file sits under a prefix its layer marked immutable
	// (content-hashed), so it may be cached for a year. Set by Lookup only.
	Immutable bool
}

Result is the outcome of a Lookup.

Found      → an exact file; serve Body (200) or 304 on ETag match.
!Found && Owned → request is under a static-owned directory prefix;
                  the op must answer 404 (NOT fall through).
!Found && !Owned → not static's; the op returns "{}" (keep routing).

Jump to

Keyboard shortcuts

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