use tokio::task::JoinHandle;
use tokio_util::sync::CancellationToken;
use crate::cores::Cores;
pub struct SelfAnnounceConfig {
pub http_port: u16,
pub dashboard_enabled: bool,
pub announce_http: bool,
pub announce_mcp: bool,
pub dns_zone: String,
}
pub fn spawn(
cores: &Cores,
cfg: SelfAnnounceConfig,
cancel: CancellationToken,
tasks: &mut Vec<JoinHandle<()>>,
) {
if cores.mdns.is_none() || (!cfg.announce_http && !cfg.announce_mcp) {
return;
}
let cores = cores.clone();
tasks.push(tokio::spawn(async move {
let hostname = crate::announce::local_hostname();
let mut posture_rx = cores.certmesh.as_ref().map(|c| c.watch_posture());
let mut http_id = crate::announce::http_record(
&cores,
cfg.http_port,
cfg.dashboard_enabled,
cfg.announce_http,
)
.await;
let mcp_id = crate::announce::mcp_record(
&cores,
&hostname,
cfg.http_port,
&cfg.dns_zone,
cfg.announce_mcp,
)
.await;
match posture_rx.as_mut() {
Some(rx) if cfg.announce_http => loop {
tokio::select! {
_ = cancel.cancelled() => break,
changed = rx.changed() => {
if changed.is_err() {
tracing::warn!(
"self-announce: certmesh posture watch closed before shutdown; \
withdrawing records and stopping re-announce"
);
break;
}
if let (Some(old), Some(mdns)) = (http_id.take(), cores.mdns.as_ref()) {
let _ = mdns.unregister(&old);
}
http_id = crate::announce::http_record(
&cores,
cfg.http_port,
cfg.dashboard_enabled,
cfg.announce_http,
)
.await;
}
}
},
_ => {
cancel.cancelled().await;
}
}
if let (Some(id), Some(mdns)) = (http_id, cores.mdns.as_ref()) {
let _ = mdns.unregister(&id);
}
crate::announce::withdraw_mcp(&cores, &hostname, &cfg.dns_zone, mcp_id.as_deref());
}));
}