Skip to content

Commit d61eaac

Browse files
committed
fix: recover outbound opens via live secondary handles
1 parent 12df96e commit d61eaac

4 files changed

Lines changed: 604 additions & 49 deletions

File tree

src/protocol/notification/config.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,14 @@ impl Config {
9393
let (notif_tx, notif_rx) = channel(DEFAULT_CHANNEL_SIZE);
9494
let (command_tx, command_rx) = channel(DEFAULT_CHANNEL_SIZE);
9595
let handshake = Arc::new(RwLock::new(handshake));
96-
let handle =
97-
NotificationHandle::new(event_rx, notif_rx, command_tx, Arc::clone(&handshake));
96+
let handle = NotificationHandle::new(
97+
protocol_name.clone(),
98+
sync_channel_size,
99+
event_rx,
100+
notif_rx,
101+
command_tx,
102+
Arc::clone(&handshake),
103+
);
98104

99105
(
100106
Self {

src/protocol/notification/handle.rs

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ impl NotificationSink {
170170
/// Handle allowing the user protocol to interact with the notification protocol.
171171
#[derive(Debug)]
172172
pub struct NotificationHandle {
173+
/// Protocol name served by this handle.
174+
protocol_name: ProtocolName,
175+
176+
/// Configured synchronous channel size.
177+
sync_channel_size: usize,
178+
173179
/// RX channel for receiving events from the notification protocol.
174180
event_rx: Receiver<InnerNotificationEvent>,
175181

@@ -195,12 +201,16 @@ pub struct NotificationHandle {
195201
impl NotificationHandle {
196202
/// Create new [`NotificationHandle`].
197203
pub(crate) fn new(
204+
protocol_name: ProtocolName,
205+
sync_channel_size: usize,
198206
event_rx: Receiver<InnerNotificationEvent>,
199207
notif_rx: Receiver<(PeerId, BytesMut)>,
200208
command_tx: Sender<NotificationCommand>,
201209
handshake: Arc<RwLock<Vec<u8>>>,
202210
) -> Self {
203211
Self {
212+
protocol_name,
213+
sync_channel_size,
204214
event_rx,
205215
notif_rx,
206216
command_tx,
@@ -401,9 +411,34 @@ impl NotificationHandle {
401411
Err(error) => match error {
402412
NotificationError::NoConnection => Err(NotificationError::NoConnection),
403413
NotificationError::ChannelClogged => {
404-
let _ = self.clogged.insert(peer).then(|| {
405-
self.command_tx.try_send(NotificationCommand::ForceClose { peer })
406-
});
414+
if self.clogged.insert(peer) {
415+
match self.command_tx.try_send(NotificationCommand::ForceClose { peer })
416+
{
417+
Ok(()) => tracing::warn!(
418+
target: LOG_TARGET,
419+
?peer,
420+
protocol = %self.protocol_name,
421+
sync_channel_size = self.sync_channel_size,
422+
"sync notification channel clogged, queueing force close",
423+
),
424+
Err(error) => tracing::warn!(
425+
target: LOG_TARGET,
426+
?peer,
427+
protocol = %self.protocol_name,
428+
sync_channel_size = self.sync_channel_size,
429+
?error,
430+
"sync notification channel clogged, failed to queue force close",
431+
),
432+
}
433+
} else {
434+
tracing::debug!(
435+
target: LOG_TARGET,
436+
?peer,
437+
protocol = %self.protocol_name,
438+
sync_channel_size = self.sync_channel_size,
439+
"sync notification channel still clogged, force close already queued",
440+
);
441+
}
407442

408443
Err(NotificationError::ChannelClogged)
409444
}
@@ -479,7 +514,14 @@ impl Stream for NotificationHandle {
479514
}
480515
InnerNotificationEvent::NotificationStreamClosed { peer } => {
481516
self.peers.remove(&peer);
482-
self.clogged.remove(&peer);
517+
if self.clogged.remove(&peer) {
518+
tracing::debug!(
519+
target: LOG_TARGET,
520+
?peer,
521+
protocol = %self.protocol_name,
522+
"cleared clogged state after notification stream closed",
523+
);
524+
}
483525

484526
return Poll::Ready(Some(NotificationEvent::NotificationStreamClosed {
485527
peer,
@@ -501,22 +543,24 @@ impl Stream for NotificationHandle {
501543
handshake,
502544
}));
503545
}
504-
InnerNotificationEvent::NotificationStreamOpenFailure { peer, error } =>
546+
InnerNotificationEvent::NotificationStreamOpenFailure { peer, error } => {
505547
return Poll::Ready(Some(
506548
NotificationEvent::NotificationStreamOpenFailure { peer, error },
507-
)),
549+
))
550+
}
508551
},
509552
}
510553

511554
match futures::ready!(self.notif_rx.poll_recv(cx)) {
512555
None => return Poll::Ready(None),
513-
Some((peer, notification)) =>
556+
Some((peer, notification)) => {
514557
if self.peers.contains_key(&peer) {
515558
return Poll::Ready(Some(NotificationEvent::NotificationReceived {
516559
peer,
517560
notification,
518561
}));
519-
},
562+
}
563+
}
520564
}
521565
}
522566
}

src/protocol/notification/mod.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,8 +1409,9 @@ impl NotificationProtocol {
14091409
let (tx, rx) = oneshot::channel();
14101410
self.pending_validations.push(Box::pin(async move {
14111411
match rx.await {
1412-
Ok(ValidationResult::Accept) =>
1413-
(peer, ValidationResult::Accept),
1412+
Ok(ValidationResult::Accept) => {
1413+
(peer, ValidationResult::Accept)
1414+
}
14141415
_ => (peer, ValidationResult::Reject),
14151416
}
14161417
}));
@@ -1827,7 +1828,22 @@ impl NotificationProtocol {
18271828
}
18281829
}
18291830
NotificationCommand::ForceClose { peer } => {
1830-
let _ = self.service.force_close(peer);
1831+
tracing::warn!(
1832+
target: LOG_TARGET,
1833+
?peer,
1834+
protocol = %self.protocol,
1835+
"processing force close command after notification channel clog",
1836+
);
1837+
1838+
if let Err(error) = self.service.force_close(peer) {
1839+
tracing::warn!(
1840+
target: LOG_TARGET,
1841+
?peer,
1842+
protocol = %self.protocol,
1843+
?error,
1844+
"failed to force close connection after notification channel clog",
1845+
);
1846+
}
18311847
}
18321848
#[cfg(feature = "fuzz")]
18331849
NotificationCommand::SendNotification{ .. } => unreachable!()

0 commit comments

Comments
 (0)