-
Notifications
You must be signed in to change notification settings - Fork 957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the ability for the behaviour to disconnect a peer #2110
Conversation
* Add 'NetworkBehaviourAction::DisconnectPeer' * Add 'ExpandedSwarm::disconnect_peer_id' * Add 'test_swarm_disconnect', 'test_behaviour_disconnect_all', 'test_behaviour_disconnect_one'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a need for Swarm::disconnect_peer
the other day and was surprised that it doesn't exist. I am in favor of this!
Implementation looks good to me, left some minor comments!
swarm/src/behaviour.rs
Outdated
DisconnectPeer { | ||
/// The peer to disconnect. | ||
peer_id: PeerId, | ||
/// The ID of the connection whose `ProtocolsHandler` to disconnect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These docs seems to be slightly off given that DisconnectPeerHandler
is not just the ID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The ID of the connection whose `ProtocolsHandler` to disconnect. | |
/// Whether to close a specific or all connections to the given peer. |
swarm/src/behaviour.rs
Outdated
|
||
/// The options which connection handlers to disconnect. | ||
#[derive(Debug, Clone)] | ||
pub enum DisconnectPeerHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs mention the term Options
, maybe DisconnectOptions
is a better name for this?
I'd also agree to DisconnectPeer
but DisconnectPeerHandler
is a bit weird. In the end, we are disconnecting the actual peer, not the handler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose someone would like to disconnect a specified connection by its ConnectionId
. DisconnectPeer
may confuse in this case.
In the end, we are disconnecting the actual peer, not the handler.
I tried to follow the style of naming structures and enumerations that you follow :)
For example, here.
The docs mention the term Options, maybe DisconnectOptions is a better name for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to follow the style of naming structures and enumerations that you follow :)
I did see that and thought you would have been inspired by NotifyHandler
:)
What about CloseConnection::{One,All}
? That naming would be inline with ProtocolsHandlerEvent::Close
although that rename would affect the overall terminology used in PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be in favor of calling both the NetworkBehaviourAction
CloseConnection
(see my comment above) and this struct CloseConnection
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First off, thanks @sergeyboyko0791 for the extensive pull request.
In general, I am not opposed to these changes.
I would like to use this opportunity to give users more guidance on which mechanism to use, now that we are adding yet another one. I guess guidance would be best given via additional documentation.
Today, as a user of libp2p-swarm
, I see two ways to close a connection to a peer:
- Via
ProtocolsHandler::keep_alive
in a collaborative manner across protocol handlers. - Via
ProtocolsHandlerEvent::Close
in a direct manner, instantly closing the connection whether used by other handlers or not.
Being able to close a connection from a NetworkBehaviour
by emitting a NetworkBehaviourAction
is a shortcut for (1). While I see this to be useful for people wanting to implement a Connection Manager via a NetworkBehaviour
, I don't think this non-collaborative style of closing connections is suitable for other protocols like libp2p-kad
or libp2p-gossipsub
.
Now, in order to be able to give users guidance on which mechanism to use when, I would like to understand your use-case @sergeyboyko0791. Would you mind expanding on why you need to close a connection from a NetworkBehaviour
?
I had a need for Swarm::disconnect_peer the other day and was surprised that it doesn't exist. I am in favor of this!
To get more data points, would you mind expanding on your use-case as well @thomaseizinger?
Please look at the example of using NetworkBehaviourAction::DisconnectPeer': https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2.1/mm2src/mm2_libp2p/src/adex_ping.rs#L27
With the default PingConfig
, libp2p-ping
should close the connection on the second failure. Is that not the case for you? If so, would you mind either debugging this yourself or providing a reproducer?
swarm/src/behaviour.rs
Outdated
/// Instructs the `Swarm` to initiate a graceful close of the connection | ||
/// with a peer. | ||
DisconnectPeer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Instructs the `Swarm` to initiate a graceful close of the connection | |
/// with a peer. | |
DisconnectPeer { | |
/// Instructs the `Swarm` to initiate a graceful close of one or all connections | |
/// with the given peer. | |
CloseConnection { |
This naming would be more intuitive to me. What do you think @sergeyboyko0791?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with you and @thomaseizinger
swarm/src/behaviour.rs
Outdated
|
||
/// The options which connection handlers to disconnect. | ||
#[derive(Debug, Clone)] | ||
pub enum DisconnectPeerHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be in favor of calling both the NetworkBehaviourAction
CloseConnection
(see my comment above) and this struct CloseConnection
.
swarm/src/lib.rs
Outdated
@@ -463,6 +464,18 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>, | |||
self.banned_peers.remove(&peer_id); | |||
} | |||
|
|||
/// Disconnects a peer by its peer ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Disconnects a peer by its peer ID. | |
/// Disconnects a peer by its peer ID, closing all connections to said peer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
swarm/src/behaviour.rs
Outdated
/// Disconnect a particular connection handler. | ||
One(ConnectionId), | ||
/// Disconnect all connection handlers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Disconnect a particular connection handler. | |
One(ConnectionId), | |
/// Disconnect all connection handlers. | |
/// Disconnect a particular connection. | |
One(ConnectionId), | |
/// Disconnect all connections. |
Your changes closes the connection. The handler is not actively being closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks!
My usecase were the examples for the
To do this, I wanted an API on For what it is worth, I think neither of the two existing approaches work very well here because the decision to disconnect is made on an application level. The individual |
Hi @mxinden, thanks for your reply and suggestions.
To be honest, I have not completely figured out how
We have one more example where we disconnect a peer using We maintain the max number of connected relays regarding the Please, look at this. |
* Rename 'NetworkBehaviourAction::DisconnectPeer' to 'NetworkBehaviourAction::CloseConnection' * Rename `DisconnectPeerHandler` to `CloseConnection`
I've pushed the changes you requested. Could you please review it again? |
Thanks. I will take a look likely later today. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing test cases for each of the 3 new ways to disconnect a peer! Very much appreciated @sergeyboyko0791.
I have a couple smaller suggestions around documentation, in order to guide users. What do you think?
Also, could you please apply the diff below adding a changelog entry:
diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md
index 103f88d2..0f01b314 100644
--- a/swarm/CHANGELOG.md
+++ b/swarm/CHANGELOG.md
@@ -15,7 +15,12 @@
See [PR 2100] for details.
+- Add `ExpandedSwarm::disconnect_peer_id` and
+ `NetworkBehaviourAction::CloseConnection` to close connections to a specific
+ peer via an `ExpandedSwarm` or `NetworkBehaviour`. See [PR 2110] for details.
+
[PR 2100]: https://github.com/libp2p/rust-libp2p/pull/2100
+[PR 2110]: https://github.com/libp2p/rust-libp2p/pull/2110/
swarm/src/behaviour.rs
Outdated
/// The peer to disconnect. | ||
peer_id: PeerId, | ||
/// The ID of the connection whose `ProtocolsHandler` to disconnect. | ||
handler: CloseConnection, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handler: CloseConnection, | |
connection: CloseConnection, |
swarm/src/behaviour.rs
Outdated
@@ -373,3 +387,18 @@ impl Default for DialPeerCondition { | |||
DialPeerCondition::Disconnected | |||
} | |||
} | |||
|
|||
/// The options which connection handlers to disconnect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The options which connection handlers to disconnect. | |
/// The options which connections to close. |
swarm/src/behaviour.rs
Outdated
DisconnectPeer { | ||
/// The peer to disconnect. | ||
peer_id: PeerId, | ||
/// The ID of the connection whose `ProtocolsHandler` to disconnect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The ID of the connection whose `ProtocolsHandler` to disconnect. | |
/// Whether to close a specific or all connections to the given peer. |
swarm/src/lib.rs
Outdated
@@ -463,6 +464,18 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>, | |||
self.banned_peers.remove(&peer_id); | |||
} | |||
|
|||
/// Disconnects a peer by its peer ID, closing all connections to said peer. | |||
/// | |||
/// Returns `Ok(())` if a peer with this ID was in the list. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Returns `Ok(())` if a peer with this ID was in the list. | |
/// Returns `Ok(())` if there was one or more established connections to the peer |
swarm/src/lib.rs
Outdated
})) | ||
} | ||
|
||
/// Establishes a number of connections between two peers, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Establishes a number of connections between two peers, | |
/// Establishes multiple connections between two peers, |
swarm/src/lib.rs
Outdated
|
||
/// Establishes a number of connections between two peers, | ||
/// after which one peer disconnects the other | ||
/// using [`NetworkBehaviourAction::CloseConnection`] thrown from a behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// using [`NetworkBehaviourAction::CloseConnection`] thrown from a behaviour. | |
/// using [`NetworkBehaviourAction::CloseConnection`] returned by a [`NetworkBehaviour`]. |
swarm/src/lib.rs
Outdated
@@ -1256,4 +1455,83 @@ mod tests { | |||
} | |||
})) | |||
} | |||
|
|||
/// Establishes a number of connections between two peers, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Establishes a number of connections between two peers, | |
/// Establishes multiple connections between two peers, |
swarm/src/lib.rs
Outdated
|
||
/// Establishes a number of connections between two peers, | ||
/// after which one peer closes the only one connection | ||
/// using [`NetworkBehaviourAction::CloseConnection`] thrown from a behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// using [`NetworkBehaviourAction::CloseConnection`] thrown from a behaviour. | |
/// using [`NetworkBehaviourAction::CloseConnection`] returned by a [`NetworkBehaviour`]. |
swarm/src/lib.rs
Outdated
@@ -1256,4 +1455,83 @@ mod tests { | |||
} | |||
})) | |||
} | |||
|
|||
/// Establishes a number of connections between two peers, | |||
/// after which one peer closes the only one connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// after which one peer closes the only one connection | |
/// after which one peer closes a single connection |
* Rename 'NetworkBehaviourAction::CloseConnection::handler' to 'NetworkBehaviourAction::CloseConnection::connection'
@mxinden, all done. |
I almost prepared the fix :D |
Thank you @mxinden @thomaseizinger for the review! |
Currently, we use a custom version of the rust-libp2p crate in the https://github.com/KomodoPlatform/atomicDEX-API project that allows us to disconnect peers from the network behaviour.
I would like to propose this functionality to allow the users to build their custom behaviors with the ability to disconnect peers.
Please look at the example of using
NetworkBehaviourAction::DisconnectPeer'
: https://github.com/KomodoPlatform/atomicDEX-API/blob/mm2.1/mm2src/mm2_libp2p/src/adex_ping.rs#L27