Documentation
¶
Overview ¶
Package hold is the platform-wide hold (ADR-0206 Decision 6): <storage.dataDir>/.hold exists iff the platform is held, every side-effect runner asks the Gate before it acts, and only the release deletes the marker. A restore in progress leaves restore.inprogress, which refuses a start until the operator empties what it wrote (Decision 2).
Index ¶
- Constants
- func Begin(dataDir, command string) error
- func End(dataDir string) error
- func Own(ref string, roots ...string) error
- func Write(dataDir string, m Marker) error
- func WriteFile(op, dir, name string, data []byte) error
- func WriteReport(dataDir string, report json.RawMessage) error
- type Evidence
- type Gate
- type Hold
- type Marker
Constants ¶
const MarkerFile, BusyFile, ReleasedFile = ".hold", "restore.inprogress", ".hold-released"
The files the hold keeps in the data directory; BusyFile marks a restore in progress (Decision 2).
const ReportFile = "restore.json"
ReportFile is restore.json, the report restore run writes beside the marker (Decision 2 step 5).
Variables ¶
This section is empty.
Functions ¶
func Begin ¶
Begin writes BusyFile naming command (run, kv, blob); a BusyFile naming another command is fault.Conflict. One naming the same command is a rerun after a kill, whose directories the command itself found empty.
func Own ¶
Own gives each root that exists, and everything below it, ref's owner and group where they differ (os.Lchown), so a restore run as root leaves what funcd, running as the data directory's owner, can open (ADR-0026 §4).
func WriteFile ¶
WriteFile replaces dir/name with data, mode 0600: a temporary file synced and renamed, then the directory synced, so a crash leaves the old file or the new one. op names the caller in the error; ADR-0207's safemode.json uses it.
func WriteReport ¶
func WriteReport(dataDir string, report json.RawMessage) error
WriteReport writes ReportFile, mode 0600, synced as Write is.
Types ¶
type Evidence ¶
type Evidence struct {
Held bool `json:"held"`
Marker *Marker `json:"marker,omitempty"`
ReleasedAt *v1.Timestamp `json:"releasedAt,omitempty"`
Report json.RawMessage `json:"report,omitempty"`
Counts map[v1.Kind]int `json:"counts,omitempty"`
PausedRuns []string `json:"pausedRuns,omitempty"`
DeadLetters []string `json:"deadLetters,omitempty"`
Pending map[string]map[string]int `json:"pending,omitempty"`
Orphans []string `json:"orphans,omitempty"`
BucketOrphans []string `json:"bucketOrphans,omitempty"`
FunctionsNotReady []string `json:"functionsNotReady,omitempty"`
}
Evidence is what the hold shows the operator (Decisions 1, 8): GET …/hold returns it, `funcdctl hold status` prints it. Report is restore.json as written; runs and dead letters are <ns>/<name> and <ns>/<id>; Pending is, per <ns>/<source>, the blob keys per event a release replays; Orphans and BucketOrphans are data no object names, which the reclaims would drop; FunctionsNotReady are <ns>/<name>.
type Gate ¶
Gate is what a runner asks: Held, and the time of the last release (zero when none).
var Never Gate = never{}
Never is the gate of a platform without a hold: never held, never released.
type Hold ¶
type Hold struct {
// contains filtered or unexported fields
}
Hold is the opened hold of one data directory, a Gate whose release is live.
func Open ¶
Open reads the hold of dataDir: BusyFile ⇒ fault.Conflict naming the interrupted restore; no marker ⇒ not held; a file that does not read or decode ⇒ fault.Internal.
func (*Hold) Release ¶
Release lifts the hold (Decision 8): it writes now to ReleasedFile, deletes the marker, syncs the directory, then lifts the gate. Not held ⇒ fault.Conflict.
func (*Hold) ReleasedAt ¶
ReleasedAt is the time the last release wrote to ReleasedFile, zero when none did.