swarm-controller: keep retrying the forge webhook secret and registration after a startup outage
The webhook secret slot is filled in the background, on the forge token's capped unbounded backoff, when the store can't answer at start. The hook registration waits for the secret and retries on the same backoff instead of giving up after five tries. Closes #6101
This commit is contained in:
parent
431cb6e77f
commit
68b38a9d44
1 changed files with 284 additions and 114 deletions
|
|
@ -93,17 +93,17 @@ pub(crate) struct AppState {
|
|||
/// either has or does not. `POST /api/forge/users/{name}/admin` reads
|
||||
/// it for every name and refuses when it cannot (`admin_unless_agent`).
|
||||
pub(crate) auth: Option<Arc<auth::AuthBridge>>,
|
||||
/// HMAC secret for swarm-wide forge webhooks, loaded once at startup.
|
||||
/// `None` when it could not be read or created — the webhook endpoint
|
||||
/// then refuses every delivery with 503 rather than admitting one it
|
||||
/// cannot verify. Deliberately not fatal to startup: nothing is
|
||||
/// registered against that endpoint yet, and the rest of this daemon's
|
||||
/// surface is unaffected. See [`load_or_generate_secret`](crate::webhook::load_or_generate_secret).
|
||||
/// HMAC secret for swarm-wide forge webhooks. Empty while it could not be
|
||||
/// read or created — the webhook endpoint then refuses every delivery with
|
||||
/// 503 rather than admitting one it cannot verify, and the hook
|
||||
/// registration waits — and filled by [`load`](crate::webhook::load)
|
||||
/// once the store answers. Deliberately not fatal to startup: the rest of
|
||||
/// this daemon's surface is unaffected.
|
||||
///
|
||||
/// `Arc<str>`, not `Arc<String>`: the value is never mutated after
|
||||
/// startup, and this way `as_deref()` yields the `&str` the verifier
|
||||
/// takes without a second hop through `String`.
|
||||
pub(crate) webhook_secret: Option<Arc<str>>,
|
||||
/// `Arc<str>`, not `Arc<String>`: the value is never mutated once set, and
|
||||
/// this way `AsRef::as_ref` yields the `&str` the verifier takes without a
|
||||
/// second hop through `String`.
|
||||
pub(crate) webhook_secret: Late<Arc<str>>,
|
||||
/// Last successful `agent-configs/*` scan, kept current by
|
||||
/// [`config_pr::spawn`]. Empty while this daemon has no forge access —
|
||||
/// same "absent means don't ask" shape as `status` and `forge`, not a
|
||||
|
|
@ -296,7 +296,7 @@ pub(crate) mod tests {
|
|||
reported_inference: None,
|
||||
agent_login: None,
|
||||
jobq: std::sync::Arc::clone(&sched),
|
||||
webhook_secret: None,
|
||||
webhook_secret: std::sync::Arc::default(),
|
||||
config_prs: std::sync::Arc::default(),
|
||||
swarm_name: None,
|
||||
// No bridge: these tests drive agent *creation*, which queues a
|
||||
|
|
|
|||
Loading…
Reference in a new issue