Documentation
¶
Overview ¶
Package sidecar is the durable-file discipline Atlas's design-time stores share.
Deployments, drafts, projects, forms, workers, the secret vault and the rest all persist small records as one file per key under a directory (ADR-0019, ADR-0021). They differ in what they store and agree completely on how to put it on disk: temp file, fsync, rename, fsync the directory. That sequence lives here once, so "nil error means the record is durable" is one implementation rather than sixteen — the same durable-before-visible rule the engine's log follows (I2 / ADR-0005), applied to the sidecar files beside it.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FsyncDir ¶
FsyncDir fsyncs a directory so a create/rename/remove of a file within it is itself durable.
func WriteFile ¶
WriteFile writes raw bytes to path with the same discipline WriteJSON gives a record. It exists because not every durable artifact is JSON — a process documentation PDF (ADR-0143) is opaque bytes stored beside its sidecar, and it deserves the same "nil error means on disk" guarantee.
Types ¶
type Option ¶
Option configures a Store at construction. The defaults cover the common case (hex-encoded filenames, listing in filename order); an option is only needed where a store genuinely differs.
func Names ¶
Names replaces the default filename scheme. enc maps a record's key to its filename stem, and ok reports whether a stem found in the directory is one of this store's records — the guard that lets an unrelated file share the directory without breaking a listing.
The default hex-encodes the key, which is what makes an arbitrary BPMN id or email address a safe, unique, deterministic filename. Override it only when the key is already filename-safe *and* recognizable: a hex token, a decimal entity key.
type Store ¶
type Store[T any] struct { // contains filtered or unexported fields }
Store is a durable store for one kind of design-time record: one JSON file per key under a single directory, written with the durability discipline above.
Atlas has sixteen of these — drafts, projects, forms, workers, deployments, releases, users, deploy tokens and the rest. They differ in what they store, how a record names itself, and what order a listing comes back in. They agreed on everything else, which is what this type now holds: create the directory, encode the key into a safe filename, write atomically, read back, ignore files that are not ours, delete idempotently.
Like the stores it replaces, a Store does no locking of its own, and it needs none: it keeps no mutable memory, so every method is a syscall against the directory. Writing is still the run-loop goroutine's alone — it is the single writer of design-time state, and a check-then-write ("is this username taken?") is atomic only because both halves happen inside one loop turn.
Reading is not confined to the loop. A record is replaced by an atomic rename (see WriteJSON), so a concurrent reader sees the whole old record or the whole new one and never a torn one, and a temp file is not named like a record so a listing never picks one up. A caller that must not wait for the engine may therefore read directly — which is what keeps signing in independent of how busy the processor is (ADR-0265).
func NewStore ¶
NewStore opens (creating if needed) the directory backing a store. name is the prefix every error from this store carries, so a failure names the store it came from; key extracts a record's identity, which is what Save files it under.
func (*Store[T]) Delete ¶
Delete removes the record filed under key. A missing record — or a key that could never name one — is not an error, so cleanup is idempotent.
func (*Store[T]) Dir ¶
Dir is the directory the store's records live in. Callers that keep sibling artifacts beside a record — a documentation PDF (ADR-0143) — need it.
func (*Store[T]) FileFor ¶
FileFor maps a key to its record path. It is a pure path helper and does not check the key — the entry points below do that; call it only with a key you have already addressed the store with.
func (*Store[T]) Get ¶
Get returns the record filed under key, or ok=false if there is none. A missing record is a normal state, not an error, and so is a key that could never name one.
func (*Store[T]) LoadAll ¶
LoadAll reads every record in the store, in the order set by Order. Files that are not this store's records — a stray temp file, a sibling artifact, a subdirectory — are skipped rather than failing the listing, and so is a record deleted between the listing and its read, which is what a reader running off the run loop can meet.