Held connections on a resolver's adapters
Held connections
The object API publishes what it stands on at the vault the same way, in
~/.stado/resolver-vault.json: per bearer key (an object namespace, a
release publisher item, the host-health role) the czekam line of the
consultation holding it with open_since, and the blad czekania line of
the last one that failed. It is the document /api/state.json serves under
vault, written on every change, so it answers with the process stopped.
stado resolver status lists it under vault and turns two states into
blockers: a key whose last consultation failed (the object API's last consultation of the vault under <key> failed, so requests under <key> are refused with that line while one of them consults again: …) and a key held
longer than the refresh interval (… has stood <N>s, longer than the <N>s directory refresh, and every request under <key> is refused behind it: …).
A document that is there and cannot be read is a blocker naming the file.
tests/storage/vault_consultation/ proves the file follows the live
document through a held read and a revoked grant.
The resolver itself refuses the same way. A new connection accepted on an
adapter whose published list already holds one unanswered longer than the
refresh interval is not relayed: before anything is read from the client the
adapter writes the refusal with the held wait's own sentence (not relayed: this host's resolver holds <N> connection(s) on that adapter unanswered longer than the <N>s refresh interval it declares, …) and closes, so a
client that does not read ~/.stado/resolver-waiting.json — a curl in a
git hook, a program on another machine — learns at once what it would
otherwise learn never. The held connection keeps its place in stado resolver status; no clock ends it on its behalf.
One thing does end it from the resolver's side: the adapter's listener
running out of file descriptors. Every held connection is a descriptor the
resolver keeps for a request nothing answers, and an adapter whose accept
fails with Too many open files serves nobody at all. On that one accept
error the resolver ends every relay that has waited longer than the refresh
interval the target declares, answers each such client with an HTTP 502
whose body is this host's resolver ran out of file descriptors accepting on <bind> (<accept error>): this connection had waited longer than the <N>s refresh interval for an answer that never came, so the resolver ended it to accept again, logs each shed wait as stado resolver adapter service=<s> consumer=<c> shed the wait of <client> to <endpoint> on <host> held since <instant> and the count as shed <N> held relay(s) after <error> and accepts again; <M> held wait(s) stand on channels still opening, gives their places
back, and accepts again. A wait still opening its channel to the host
(phase: open) stands on the SSH session, not on a relay, and is not shed.
When no held relay is older than the interval, the adapter ends as before
and stado resolver status shows failed with <bind> accept failed: <error>; no relay older than the <N>s refresh interval could be shed (<M> held wait(s) stand on channels still opening), so the descriptors are held by something this adapter cannot free.
Source: this website