hive-c0re + harness: filter agent-sockets.json by .bound marker (#784, atlas concern)
closes the gate atlas raised on PR #813: without per-agent opt-in signal, agent-sockets.json listed every sub-agent, and any agent that hadn't flipped hyperhive.web.useUnixSocket would 502 the gateway (its harness still binds TCP, no socket at the published path). harness side (web_ui::bind_unix): - after successful bind + chmod, drop a `.bound` marker in the per-agent dir as a stable 'this agent has a unix socket here' signal. best-effort: a failed marker write logs at WARN but doesn't abort serve (the socket still binds fine; gateway just keeps using TCP for one more poll). c0re side (agent_sockets): - new READY_MARKER const + ready_marker_for(name) helper - build_map filters by ready_marker_for(name).exists() — only agents whose harness has bound the socket appear in the JSON map - new build_map_with<F> internal extracts the predicate so tests pass a controlled is_ready closure (no real fs access) - new spawn_poll() background task: re-fires agent_sockets::write every 10s so the JSON catches up to fresh markers without needing a container-start hook. write() idempotency means steady-state cost is one stat per agent per tick. 10 tests: 6 prior + new build_map_filters_by_ready_predicate + ready_marker_path_is_sibling_of_socket. existing tests adjusted to call build_map_with(_, |_| true) since the default path now hits the fs. once this lands + #822 lands, atlas's gateway-side step 3 can drop its eval-time `pathExists` fallback — c0re only publishes opted-in agents, so the gateway can trust the JSON unconditionally.
This commit is contained in:
parent
777d26812a
commit
5e0cb5e0f5
3 changed files with 140 additions and 8 deletions
|
|
@ -195,6 +195,24 @@ fn bind_unix(path: &Path) -> Result<tokio::net::UnixListener> {
|
|||
use std::os::unix::fs::PermissionsExt;
|
||||
std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o660))
|
||||
.with_context(|| format!("set perms on {}", path.display()))?;
|
||||
// Drop a `.bound` marker next to the socket so c0re's
|
||||
// `agent_sockets::write` can filter the JSON map to only include
|
||||
// agents whose harness has actually opted in to (and bound) the
|
||||
// unix socket. Without this gating, gateway would `proxy_pass`
|
||||
// to a non-existent socket for any sub-agent that hasn't flipped
|
||||
// `hyperhive.web.useUnixSocket = true` yet — atlas's concern on
|
||||
// PR #813. Best-effort: a failed write isn't fatal (the harness
|
||||
// still binds + serves on the socket), it just means the
|
||||
// gateway side keeps using the TCP upstream for one more sync.
|
||||
if let Some(parent) = path.parent() {
|
||||
let marker = parent.join(".bound");
|
||||
if let Err(e) = std::fs::write(&marker, b"") {
|
||||
tracing::warn!(
|
||||
marker = %marker.display(), error = %e,
|
||||
"failed to write .bound marker — gateway may keep TCP upstream"
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(listener)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue