TopicManager
The TopicManager is the central coordinator — it owns a single Zenoh session shared across all pub/sub pairs, reducing memory and connection overhead. One session, many pub/sub pairs. The TopicManager eliminates per-topic connection overhead.Shared session
Shared session
Automatic discovery
Automatic discovery
Subscribers announce themselves on the network. When a remote subscriber appears, the TopicManager auto-enables network publishing for that topic. When the last subscriber disconnects, network publishing stops — no wasted serialization.
Type safety
Type safety
The TopicManager validates that publishers and subscribers on the same topic use the same message type. Mismatches are caught at startup, not at runtime.
Keep-alive tracking
Keep-alive tracking
Remote subscribers send periodic keep-alive signals. If a subscriber goes silent, the TopicManager disables network publishing for that topic — saving CPU cycles that would otherwise be spent serializing data nobody receives.
Publisher
The Publisher uses a dual-path architecture: local publishing is synchronous and fast, network publishing happens asynchronously on a background thread. Local publishing never waits for network I/O. Local path: ~60 ns. Network path: asynchronous, non-blocking. Both fire on every publish.Dual-path publishing
Dual-path publishing
Every
send() writes to shared memory (local subscribers) and queues for the network thread (remote subscribers) — simultaneously. Local subscribers see the data in nanoseconds. Remote subscribers get it as fast as the network allows.Non-blocking network
Non-blocking network
The network background thread serializes and transmits independently. If the network is slow or congested, local publishing continues at full speed. The publisher never blocks.
Latest-message semantics
Latest-message semantics
Only the most recent message is queued for network transmission. If the publisher sends faster than the network can deliver, stale messages are replaced — not queued. For real-time systems, current data always beats old data.
Automatic lifecycle
Automatic lifecycle
The background thread starts on creation and shuts down on drop. No manual thread management, no cleanup code. Rust’s ownership system guarantees clean shutdown.
Subscriber
The Subscriber automatically discovers topics and selects the optimal transport path. If a topic exists locally, it reads from shared memory. If not, it requests the topic over the network. Like a GPS that always picks the fastest route — local shared memory when available, network when necessary.Topic discovery
Topic discovery
Cerulion displays all available topics across every device on the network. You subscribe by name — the system handles routing.
Local-first path selection
Local-first path selection
When the topic exists on the same machine, the subscriber reads directly from the publisher’s shared memory region. No serialization, no network stack, no copies. This is why local latency is ~60 ns instead of milliseconds.
Network fallback
Network fallback
When the topic is only available on a remote machine, the subscriber requests it over Zenoh. The remote publisher starts serializing and transmitting. Latest-message semantics ensure the subscriber always gets current data.
Non-blocking receive
Non-blocking receive
When a node runs and no message is waiting on an input, the transport layer returns immediately — no blocking, no spinning. The scheduler controls when nodes execute, not the transport layer.