The registry's last-known-good copy

The last-known-good copy

The last-known-good copy holds to the same fence. Every registry read that records a copy — a command reading its store, the serving resolver's refresh — refuses a document whose service_directory.generation is below the one the copy holds, keeps the copy and says [registry-cache] not recording the last-known-good registry in <path>: the registry read names service directory generation <old>, below generation <new> this host's last-known-good copy holds; keeping the copy, because a directory generation only advances and a lower one is an authority answering after its role moved; if the copy's generation is the false one, stado resolver accept --generation <old> on this host adopts the lower one once. stado resolver status publishes it as the refusal kind directory-rollback. The resolver records its copy only after it has judged the generation, so the generation placement move --authority wrote into the copy is not replaced by the old authority's next answer; the generation the operator accepted is recorded in the copy as the resolver adopts it.

The registry is read from a remote authority once per refresh interval. When this host's resolver holds no generation it may answer from, the authority's snapshot a command read is kept for the refresh interval reads of that authority are measured by, in that process and in ~/.stado/authority-snapshot.json (STADO_AUTHORITY_SNAPSHOT_FILE moves it), and every registry read inside the interval answers from it with stado: registry read from the snapshot of the registry authority <host> this command already read; it stands <N>s more, the refresh interval reads of that authority are measured by (… an earlier command read … when another command kept it). A registry write through the process forgets both, so that command and the next read what it wrote; a record that cannot be written, read or removed is said on stderr; with no declared interval nothing is kept. stado resolver resolve, the relays that resolve a service through it, and the database plane read the directory the same way: this host's resolver's held generation, else the kept snapshot, and the authority only when neither answers, so one such command stands at most one authority read. The checks whether the authority answers now (placement move --authority, registry push --last-known-good) never take the held generation or the kept snapshot: they ask the authority, unless a read of it less than one refresh interval ago got no snapshot, which they take as its answer (see stado resolver remembered show; forget makes the next check ask). A read asks every SSH path the authority declares at once and takes the first snapshot that answers, so a first path that accepts connections and answers nothing no longer holds the read before a path that answers is tried; the reads still standing are dropped and their waits end as cut short. When none answers, the refusal names every path's own failure in the declared order (no registry authority SSH connection path answered (<path>: <cause>; …)). A registry write through the authority still tries its paths one after another, since a compare-and-swap must not be sent twice.

The copy is written on each host with stado registry push PATH|- --last-known-good [--json]. It validates the document as every push does, then refuses when the authority answers (the registry authority answers; a registry it would serve is pushed through it, without --last-known-good), when this host is the authority or keeps no copy naming one, and when the document's service_directory.generation is not above the copy's (… not above the <held> this host's last-known-good copy holds; a copy is never rolled back). Otherwise it writes the copy with the store version handed-over and prints handed <path> to this host's last-known-good copy at service directory generation <N>; the authority did not answer: <cause>, or under --json {"state": "handed-over", "directory_generation", "authority_unanswered"}. It cannot be combined with --if-generation, --force or --allow-empty-fleet.

A write the authority runs for another host is stado registry push - --if-generation <version>; with --fence-transaction <id> (not with --last-known-good) it writes through the authority's store while the storage write fence of transaction <id> holds it, the one writer that fence admits. That is the registry commit stado placement role move --with-authority sends the authority whose store the move fenced, so the authority itself serves the registry naming its successor; a fence of any other transaction still refuses the write (local storage writes are fenced by …), and one process writes for one transaction only. The admission reaches only this process's own writes to the local store, so a host whose WC_STORAGE_BACKEND names the object API is refused before anything is written (--fence-transaction <id> admits this process's writes to the local store it fenced, but this host's registry store is the object API (<url>), whose writes another process makes; …).

stado registry pull --last-known-good [--path P] prints this host's copy as it is on disk, without asking the authority or the store, so it answers while both are down; --path selects in it as pull --path does in the registry (--path service_directory.authority.target names the authority this host asks, --path service_directory.generation the generation it holds). A host that keeps no copy is refused as not found, this host keeps no last-known-good registry copy at <path>. It cannot be combined with --with-generation or --generation-only. Stado Desktop reads it as "Read this host's last-known-good registry copy".

Source: this website