hive-agent: the swarm queue connection is required; retry, then exit
An agent's harness connects to the swarm queue with the agent's own credential or not at all. The first connect retries after 5s, doubling (7 attempts, about five minutes), with a warning per failed attempt; when every attempt fails the harness logs an error and exits 1. Missing coordinates (HIVE_AGENT_NATS_URL, or the secret store's BAO_ADDR / HIVE_AGENT_NAME / certificate) fail the boot outright. Previously the first connect's outcome was memoized for the life of the process: a store 403 or queue refusal at boot left the agent on the hive's shared client, or disconnected, until someone restarted it, and an agent with no queue coordinates ran on without one. Both paths are gone, with the hive-scoped subjects that only the shared client used. The harness unit now restarts after 30s instead of 2s, so a swarm-wide outage doesn't restart every agent every 2s, and has no start limit, so it keeps coming back however long the outage lasts. The hive's shared client credential is still imported into the harness unit for swarm-logs; the two HIVE_AGENT_OIDC_*_FILE variables that pointed the harness at it are dropped, as is the unset HIVE_AGENT_OIDC_CA_FILE override. With the fallback gone, the pieces #4944 added only for it go too: swarm_input's skip-on-shared-client branch and swarm-queue-client's connect_with_inbox_prefix. swarm-nats-auth's grant for the hive's shared agent client is unchanged. Closes #4909
This commit is contained in:
parent
147b9e0a23
commit
235bc481b3
16 changed files with 392 additions and 964 deletions
|
|
@ -23,8 +23,7 @@
|
|||
//! paused is recorded as if fired, so resuming does not fire it.
|
||||
//!
|
||||
//! The list itself is held in memory only: until the first successful read
|
||||
//! after a start, nothing fires. Reading needs this agent's own credential;
|
||||
//! on the hive's shared client the task logs that and stops.
|
||||
//! after a start, nothing fires.
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
@ -35,7 +34,6 @@ use rusqlite::{Connection, OptionalExtension as _, params};
|
|||
use swarm_queue_client::agent_schedules::{AgentSchedules, Read, Schedule, read_own};
|
||||
use tokio::sync::Notify;
|
||||
|
||||
use crate::swarm_queue::{Connection as QueueConnection, Presented};
|
||||
use crate::todos::Todos;
|
||||
|
||||
/// How often the key is read and the list checked for due slots. Also the
|
||||
|
|
@ -179,12 +177,9 @@ fn push_todo(todos: &Todos, wake: &Notify, schedule: &Schedule) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Run the ticker for the harness's lifetime, if this agent has a queue
|
||||
/// credential and a label to name its key with.
|
||||
/// Run the ticker for the harness's lifetime, if this agent has a label to
|
||||
/// name its key with.
|
||||
pub async fn run(todos: Arc<Todos>, wake: Arc<Notify>) {
|
||||
if !crate::swarm_queue::configured() {
|
||||
return;
|
||||
}
|
||||
let agent = crate::identity::label();
|
||||
if agent.is_empty() {
|
||||
tracing::warn!("this agent has no label; not reading its swarm schedules");
|
||||
|
|
@ -197,16 +192,7 @@ pub async fn run(todos: Arc<Todos>, wake: Arc<Notify>) {
|
|||
return;
|
||||
}
|
||||
};
|
||||
let Some(QueueConnection { client, presented }) = crate::swarm_queue::client().await else {
|
||||
return;
|
||||
};
|
||||
if presented != Presented::Agent {
|
||||
tracing::warn!(
|
||||
"connected with the hive's shared client, which has no read grant on the \
|
||||
agent-schedules bucket; swarm schedules are not read"
|
||||
);
|
||||
return;
|
||||
}
|
||||
let client = crate::swarm_queue::client().await;
|
||||
tracing::info!(%agent, "reading swarm schedules from the swarm queue");
|
||||
let mut list: Option<AgentSchedules> = None;
|
||||
loop {
|
||||
|
|
|
|||
Loading…
Reference in a new issue