Node Discovery & Monitoring
These types are for building custom monitoring and discovery tools. Most users don't need them — the built-in Monitor handles this automatically.
NodePresence
Node presence files written to shared memory for cross-process discovery. The scheduler creates these automatically at startup; monitoring tools read them. Paths are managed by horus_sys and vary by platform.
use horus::prelude::*; // NodePresence is available via the prelude
// Discover all running HORUS nodes on this machine
let nodes = NodePresence::read_all();
for node in &nodes {
println!("{}: pid={}, rate={:?}Hz, health={:?}, ticks={}, errors={}",
node.name(), node.pid(), node.rate_hz(),
node.health_status(), node.tick_count(), node.error_count());
}
// Read a specific node
if let Some(motor) = NodePresence::read("motor_ctrl") {
println!("Publishers: {:?}", motor.publishers());
println!("Services: {:?}", motor.services());
}
| Method | Returns | Description |
|---|---|---|
name() | &str | Node name |
pid() | u32 | Process ID (verified for liveness) |
scheduler() | Option<&str> | Scheduler name |
publishers() | &[TopicMetadata] | Topics this node publishes |
subscribers() | &[TopicMetadata] | Topics this node subscribes to |
rate_hz() | Option<f64> | Configured tick rate |
health_status() | Option<&str> | Healthy / Warning / Error / Critical |
tick_count() | u64 | Total ticks since start |
error_count() | u32 | Total errors since start |
services() | &[String] | Provided services |
actions() | &[String] | Provided actions |
Static methods: read(name) → Option<Self>, read_all() → Vec<Self>
NodeAnnouncement
Real-time lifecycle events broadcast on the horus.ctl.{scheduler} topic. Unlike presence files (polled), announcements are push-based — you get notified the moment a node starts or stops.
// discovery module removed — node lifecycle managed via SchedulerRegistry + control topic
use horus::prelude::*;
let discovery: Topic<NodeAnnouncement> = Topic::new(DISCOVERY_TOPIC).unwrap();
if let Some(ann) = discovery.recv() {
match ann.event {
NodeEvent::Started => {
println!("{} started (pid={})", ann.name, ann.pid);
println!(" publishes: {:?}", ann.publishers);
println!(" subscribes: {:?}", ann.subscribers);
}
NodeEvent::Stopped => println!("{} stopped", ann.name),
}
}
| Field | Type | Description |
|---|---|---|
name | String | Node name |
pid | u32 | Process ID |
event | NodeEvent | Started or Stopped |
publishers | Vec<String> | Published topic names |
subscribers | Vec<String> | Subscribed topic names |
timestamp_ms | u64 | Event timestamp |
See Also
- Monitor Guide — Built-in web + TUI monitoring
- Scheduler API —
ProfileReportandstatus() - Topic API —
TopicMetrics