Documentation
¶
Overview ¶
Package startup tells the owner what a starting server is doing. Ether binds its port before it opens the database, and until the server is ready a Gate answers on it: the console shell and a public, read-only status (/ether/api/startup-status) render a status page, and every other route, the Plex API included, answers 503 with Retry-After. Plex clients, GDM discovery and plex.tv publication only ever see a ready server.
Index ¶
- Constants
- type Database
- type Failure
- type Gate
- type Phase
- type Status
- type Tracker
- func (t *Tracker) Begin()
- func (t *Tracker) Fail(f Failure, attempt int, retry time.Duration)
- func (t *Tracker) Phase() Phase
- func (t *Tracker) Postpone(retry time.Duration)
- func (t *Tracker) Progress(step, steps int)
- func (t *Tracker) Restoring(source string)
- func (t *Tracker) Set(phase Phase)
- func (t *Tracker) SetDatabase(db Database)
- func (t *Tracker) Snapshot() Status
- func (t *Tracker) Waiting(phase Phase, attempt int, retry time.Duration, err error)
Constants ¶
const ( FailDatabaseUnreachable = "database_unreachable" // PostgreSQL refused or timed out FailDatabaseRejected = "database_rejected" // bad password, missing database, invalid URL FailDatabaseCorrupt = "database_corrupt" // SQLite file damaged FailMigration = "migration_failed" FailCredentialKey = "credential_key" FailRestore = "restore_failed" // originals could not be put back FailConfig = "config" FailUnknown = "unknown" )
Failure codes: what went wrong, so the console can say what to do.
const RecoveryPrefix = "/ether/api/startup/recovery/"
RecoveryPrefix is where a failed start's recovery API is mounted.
const StatusPath = "/ether/api/startup-status"
StatusPath is the public, read-only startup status endpoint.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Database ¶
type Database struct {
// Kind is "sqlite" or "postgres".
Kind string `json:"kind"`
// Host is host:port (PostgreSQL only).
Host string `json:"host,omitempty"`
}
Database names the database a server is opening, without credentials.
type Failure ¶
type Failure struct {
Code string `json:"code"`
// Detail is the error, with credentials scrubbed.
Detail string `json:"detail,omitempty"`
// Recoverable is set when the start page may restore a backup (a
// standalone server, whose database is a file it can replace).
Recoverable bool `json:"recoverable,omitempty"`
}
Failure is why a start failed.
type Gate ¶
type Gate struct {
// Tracker supplies the status.
Tracker *Tracker
// Shell serves the console's static files (GET /ether/...).
Shell http.Handler
// Recovery, when set, serves RecoveryPrefix while the start has failed.
Recovery http.Handler
// Console wraps every /ether/ handler the gate serves itself (the
// owner console's network policy). Nil leaves them as they are.
Console func(http.Handler) http.Handler
// contains filtered or unexported fields
}
Gate is the server's root handler for its whole life. Until Open it serves only the startup status, the console shell and (while a start has failed) the recovery API; everything else gets 503. After Open it passes requests to the server, and Close stops doing so and waits for requests in flight, so a restart drains before the server shuts down.
func (*Gate) Close ¶
Close stops routing requests to the server (new ones get 503 and the stopping status) and waits until the requests in flight have finished or ctx ends.
type Phase ¶
type Phase string
Phase is what a starting (or stopping) server is doing.
const ( PhaseStarting Phase = "starting" // reading settings PhaseRestoring Phase = "restoring" // swapping in a restored backup PhaseWaitingDatabase Phase = "waiting_database" // PostgreSQL unreachable; retrying PhaseWaitingCluster Phase = "waiting_cluster" // older nodes must update before migrating PhaseBackingUp Phase = "backing_up" // safety copy before migrating PhaseMigrating Phase = "migrating" // applying database updates PhaseImporting Phase = "importing" // importing a restored dump PhaseCheckingIntegrity Phase = "checking_integrity" // checking a restored database PhaseStartingServices Phase = "starting_services" PhaseReady Phase = "ready" PhaseStopping Phase = "stopping" // shutting down for a restart PhaseFailed Phase = "failed" )
type Status ¶
type Status struct {
Phase Phase `json:"phase"`
Ready bool `json:"ready"`
// Message is a one-line English summary (for logs and API clients;
// the console words its own from Phase and the fields below).
Message string `json:"message"`
// Step of Steps, while a phase has countable work (migrations).
Step int `json:"step,omitempty"`
Steps int `json:"steps,omitempty"`
// Started is when this start began; Since when the phase did.
Started time.Time `json:"started"`
Since time.Time `json:"since"`
Elapsed float64 `json:"elapsedSeconds"`
// Attempt and RetryAt while waiting for the database or after a
// failure (the server retries by itself).
Attempt int `json:"attempt,omitempty"`
RetryAt *time.Time `json:"retryAt,omitempty"`
Database *Database `json:"database,omitempty"`
Failure *Failure `json:"failure,omitempty"`
// Restoring names the backup being restored.
Restoring string `json:"restoring,omitempty"`
Version string `json:"version,omitempty"`
}
Status is the startup status endpoint's document. It carries no settings and no credentials.
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
Tracker holds a start's status. It is safe for concurrent use.
func NewTracker ¶
NewTracker starts tracking a start of version.
func (*Tracker) Begin ¶
func (t *Tracker) Begin()
Begin starts a new start: a restart within the process (a cluster transition or a retry after a failure) is timed from here.
func (*Tracker) Postpone ¶
Postpone moves a failed start's next retry to retry from now (the owner is using the recovery page).
func (*Tracker) SetDatabase ¶
SetDatabase records which database is being opened.