Repository navigation
Closed
Description
Description
Replace the various NetworkBehaviour::inject_xxx methods with a single NetworkBehaviour::on_event method and a InEvent enum.
Example replacing NetworkBehaviour::inject_connection_established:
diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs
index c0ac5976..c10adb7d 100644
--- a/swarm/src/behaviour.rs
+++ b/swarm/src/behaviour.rs
@@ -191,7 +191,13 @@ pub trait NetworkBehaviour: 'static {
vec![]
}
+ fn on_event(&mut self, _event: InEvent) {}
+
/// Informs the behaviour about a newly established connection to a peer.
+ #[deprecated(
+ since = "0.39.0",
+ note = "Handle `InEvent::ConnectionEstablished` in `NetworkBehaviour::on_event` instead."
+ )]
fn inject_connection_established(
&mut self,
_peer_id: &PeerId,
@@ -778,3 +784,15 @@ impl Default for CloseConnection {
CloseConnection::All
}
}
+
+pub enum InEvent<'a> {
+ /// Informs the behaviour about a newly established connection to a peer.
+ ConnectionEstablished {
+ peer_id: PeerId,
+ connection_id: ConnectionId,
+ endpoint: &'a ConnectedPoint,
+ // TODO: Would a slice not be better?
+ failed_addresses: Option<&'a Vec<Multiaddr>>,
+ other_established: usize,
+ },
+}
diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs
index 38df855c..dfefb050 100644
--- a/swarm/src/lib.rs
+++ b/swarm/src/lib.rs
@@ -710,6 +710,14 @@ where
failed_addresses.as_ref(),
non_banned_established,
);
+ self.behaviour
+ .on_event(behaviour::InEvent::ConnectionEstablished {
+ peer_id,
+ connection_id: id,
+ endpoint: &endpoint,
+ failed_addresses: failed_addresses.as_ref(),
+ other_established: non_banned_established,
+ });
return Some(SwarmEvent::ConnectionEstablished {
peer_id,
num_established,Motivation
- Decision whether to ignore an event (e.g. the event of a new connection being established) is made at the
NetworkBehaviourtraitdefinition by providing a default implementation or not. I argue this decision should be made by the user not by libp2p, i.e. I think users should decide whether to exhaustively match on all event handlers, or ignore most through a wildcard match arm. This is especially relevant when introducing new event handlers in the future. - The amount of event handler methods is becoming too long, especially with swarm/:
NetworkBehaviour/ConnectionHandlercross-communication #2680 and swarm/: Support generic connection management through NetworkBehaviour #2828 - I find a single event handler multiplexing events through an
enummore intuitive than manyinject_xxxmethods. - Having a single
on_eventmethod helps differentiate the event handling code inNetworkBehaviourfrom the non event handling code (new_handler,addresses_of_peerandpoll).
What do folks think? Would you be in favor of this change?
Requirements
Open questions
Are you planning to do it yourself in a pull request?
Yes, unless someone else would like to.
Activity
[-]swarm/behaviour: Inject events via `NetworkBehaviour::onEvent(&mut self, event: InEvent)`[/-][+]swarm/behaviour: Inject events via single method[/+]thomaseizinger commentedon Aug 20, 2022
I agree with your concerns.
One thing to note is that the extra match will ident all code handling the event by two tabs: one for the
matchand one for the match arm.To keep things readable, users will likely extract their own functions anyway except for really simple cases which brings us back to square one with more boilerplate except that the users is more in control of which events to handle.
Another problem is that users will likely go unnoticed of new events that they should handle.
Another option would be if a
NetworkBehaviourcould "subscribe" to individual events but I am not sure how to model that in a type safe way.Unfinished thought:
We could have another macro that lets users tag functions as event handlers, thus picking the ones they want to handle and the macro would fill in the remaining ones:
This has big downsides too though:
thomaseizinger commentedon Aug 20, 2022
If we go with an enum, we could probably also unify
SwarmEventand the aboveInEvent.thomaseizinger commentedon Aug 20, 2022
Thinking about it more, a single
on_eventfunction seems like the right primitive to me. Everything else, including the macro above, can be built on top of that.dignifiedquire commentedon Aug 30, 2022
👍 in general from my side, I am always worried if I am handling all events that I need to, and this would make it a lot easier to guard against the issue.
mxinden commentedon Sep 4, 2022
Related to the change on
NetworkBehaviour, I would like to to do the corresponding change toConnectionHandleras well, namely to replace itsinject_*methods with a singleon_eventmethod. I think this does not have to happen within the same pull request, though preferably for the sake of consistency, within the same release.mxinden commentedon Sep 4, 2022
Cross-referencing implementation of this proposal #2867.
ROADMAP: Remove event handling refactoring
refactor(swarm): remove deprecated inject calls (#3264)
refactor(swarm): remove deprecated inject calls (libp2p#3264)