mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-29 17:51:35 +00:00
feat(identify): push changed listen protocols to remote
Now that we have the infrastructure for notifying protocols about changes to our listen protocols, we can use this to actively push those changes to our remotes. This allows other peers to re-configure themselves with very low-latency instead of waiting for the periodic identify event. Resolves: #3613. Pull-Request: #3980.
This commit is contained in:
@ -36,7 +36,7 @@ use libp2p_swarm::{
|
||||
ConnectionHandler, ConnectionHandlerEvent, KeepAlive, StreamProtocol, StreamUpgradeError,
|
||||
SubstreamProtocol, SupportedProtocols,
|
||||
};
|
||||
use log::warn;
|
||||
use log::{warn, Level};
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::HashSet;
|
||||
use std::{io, task::Context, task::Poll, time::Duration};
|
||||
@ -60,6 +60,9 @@ pub struct Handler {
|
||||
/// Future that fires when we need to identify the node again.
|
||||
trigger_next_identify: Delay,
|
||||
|
||||
/// Whether we have exchanged at least one periodic identify.
|
||||
exchanged_one_periodic_identify: bool,
|
||||
|
||||
/// The interval of `trigger_next_identify`, i.e. the recurrent delay.
|
||||
interval: Duration,
|
||||
|
||||
@ -122,6 +125,7 @@ impl Handler {
|
||||
events: SmallVec::new(),
|
||||
pending_replies: FuturesUnordered::new(),
|
||||
trigger_next_identify: Delay::new(initial_delay),
|
||||
exchanged_one_periodic_identify: false,
|
||||
interval,
|
||||
public_key,
|
||||
protocol_version,
|
||||
@ -238,6 +242,14 @@ impl Handler {
|
||||
|
||||
self.remote_supported_protocols = new_remote_protocols;
|
||||
}
|
||||
|
||||
fn local_protocols_to_string(&mut self) -> String {
|
||||
self.local_supported_protocols
|
||||
.iter()
|
||||
.map(|p| p.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectionHandler for Handler {
|
||||
@ -319,6 +331,7 @@ impl ConnectionHandler for Handler {
|
||||
let event = result
|
||||
.map(|()| Event::Identification)
|
||||
.unwrap_or_else(|err| Event::IdentificationError(StreamUpgradeError::Apply(err)));
|
||||
self.exchanged_one_periodic_identify = true;
|
||||
|
||||
return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event));
|
||||
}
|
||||
@ -349,7 +362,29 @@ impl ConnectionHandler for Handler {
|
||||
| ConnectionEvent::ListenUpgradeError(_)
|
||||
| ConnectionEvent::RemoteProtocolsChange(_) => {}
|
||||
ConnectionEvent::LocalProtocolsChange(change) => {
|
||||
self.local_supported_protocols.on_protocols_change(change);
|
||||
let before = log::log_enabled!(Level::Debug)
|
||||
.then(|| self.local_protocols_to_string())
|
||||
.unwrap_or_default();
|
||||
let protocols_changed = self.local_supported_protocols.on_protocols_change(change);
|
||||
let after = log::log_enabled!(Level::Debug)
|
||||
.then(|| self.local_protocols_to_string())
|
||||
.unwrap_or_default();
|
||||
|
||||
if protocols_changed && self.exchanged_one_periodic_identify {
|
||||
log::debug!(
|
||||
"Supported listen protocols changed from [{before}] to [{after}], pushing to {}",
|
||||
self.remote_peer_id
|
||||
);
|
||||
|
||||
let info = self.build_info();
|
||||
self.events
|
||||
.push(ConnectionHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: SubstreamProtocol::new(
|
||||
Either::Right(Push::outbound(info)),
|
||||
(),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user