From 5b70e40d8faadc6fbb2c13c1a1ad78cbb8807379 Mon Sep 17 00:00:00 2001 From: Alvaro Gaona Date: Sat, 7 Mar 2026 23:05:25 +0100 Subject: [PATCH] fix: prevent silent status event loss during SEDP discovery bursts The DomainParticipantStatusEvent channel had a capacity of 16 and silently dropped events when full, causing downstream consumers to miss endpoint discoveries entirely with no indication of data loss. A single participant can expose many endpoints (e.g. ~16 in a typical ROS 2 node), so even two participants overwhelm a 16-slot channel during the initial SEDP burst. Changes: - Increase status channel capacity from 16 to 2048 - Upgrade log level from trace! to warn! on channel overflow --- src/dds/participant.rs | 8 ++++++-- src/dds/statusevents.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dds/participant.rs b/src/dds/participant.rs index 749f86c0..8f9af963 100644 --- a/src/dds/participant.rs +++ b/src/dds/participant.rs @@ -226,8 +226,12 @@ impl DomainParticipantBuilder { let (discovery_command_sender, discovery_command_receiver) = mio_channel::sync_channel::(64); - // Channel used to report noteworthy events to DomainParticipant - let (status_sender, status_receiver) = sync_status_channel(16)?; + // Channel used to report noteworthy events to DomainParticipant. + // Capacity must be large enough to absorb the SEDP burst when multiple + // participants are discovered at once. A single participant can expose + // many endpoints (e.g. ~16 in a typical ROS 2 node), so 2048 handles + // large deployments without silent event loss. + let (status_sender, status_receiver) = sync_status_channel(2048)?; #[cfg(not(feature = "security"))] let security_plugins_handle = None; diff --git a/src/dds/statusevents.rs b/src/dds/statusevents.rs index fb1f713e..09fdd605 100644 --- a/src/dds/statusevents.rs +++ b/src/dds/statusevents.rs @@ -103,7 +103,7 @@ impl StatusChannelSender { Ok(()) } Err(mio_channel::TrySendError::Full(_tt)) => { - trace!("StatusChannelSender cannot send new status changes, channel is full."); + warn!("StatusChannelSender cannot send new status changes, channel is full."); // It is perfectly normal to fail due to full channel, because // no-one is required to be listening to these. self.signal_sender.send(); // kick the receiver anyway