feat(#3255): announce a knowledge change to every hive on the queue
The controller verified a knowledge delivery, logged it, and returned OK. Nothing downstream ever heard about it, so a hive learned the repository had changed only by registering its own webhook — which is the last-writer-wins contention this issue is about. The event carries no payload. The hive-side handler this replaces reads two fields from Forgejo's push webhook and uses neither — both are filters — then runs `git pull`, which re-derives everything from the repository. What crosses the queue is an edge trigger, and fields would invent a contract nobody reads. One subject per hive, so the callout policy can express "this hive may hear its own events" at all; a subject with no hive component is the same subject for every hive. `ConfigPr` deliveries are deliberately not forwarded. A hive does not want to hear that a config PR opened — it wants to be told when to rebuild from main, which the controller decides after a merge rather than by relaying this delivery. That is deploy coordination's job, and the empty arm is there so the omission reads as scoped rather than forgotten. Fails soft: a missed announcement costs a hive stale knowledge until its next boot pull, which is the same cost as a webhook delivery to a hive that was down — what this replaces. A permission failure cannot be observed at the call site (a NATS authorization violation is reported asynchronously on the connection, reaching a client as a timeout or as nothing), so the doc says the flush proves only that the bytes left this process and points at the server log.
This commit is contained in:
parent
8baf1899d8
commit
bac4a8b6a1
2 changed files with 82 additions and 0 deletions
|
|
@ -133,6 +133,23 @@ impl StatusReader {
|
|||
}
|
||||
}
|
||||
|
||||
/// A handle on the queue connection this reader holds.
|
||||
///
|
||||
/// The controller has exactly **one** connection to the swarm queue and
|
||||
/// more than one thing to do with it: status is read out of a KV bucket,
|
||||
/// swarm events are published on a subject. Handing out a clone is cheap —
|
||||
/// `async_nats::Client` is a handle, not a socket — and is strictly better
|
||||
/// than opening a second connection, which would double the auth-callout
|
||||
/// traffic and give the two paths independent reconnect state, so one could
|
||||
/// be serving while the other was still down.
|
||||
///
|
||||
/// That this lives on the *status* reader is an accident of who constructed
|
||||
/// the connection first, not a claim that events are a kind of status.
|
||||
#[must_use]
|
||||
pub fn queue_client(&self) -> async_nats::Client {
|
||||
self.client.clone()
|
||||
}
|
||||
|
||||
/// Reads [`STALE_AFTER_ENV`], falling back to
|
||||
/// [`DEFAULT_STALE_AFTER`]. A zero or unparseable value takes the
|
||||
/// default rather than failing startup — same rule as `load_hives`:
|
||||
|
|
|
|||
Loading…
Reference in a new issue