mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-14 02:21:21 +00:00
swarm/: Improve NetworkBehaviour
documentation (#2361)
- Contrast `NetworkBehaviour` and `Transport`. - Describe hierarchy of `NetworkBehaviour` implementations. - Describe `NetworkBehaviour` combinators. - Describe `NetworkBehaviour` derive macro. - Document `out_event` mechanism`. - Document `ignore` mechanism.
This commit is contained in:
@ -31,18 +31,48 @@ use std::{task::Context, task::Poll};
|
||||
type THandlerInEvent<THandler> =
|
||||
<<THandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::InEvent;
|
||||
|
||||
/// A behaviour for the network. Allows customizing the swarm.
|
||||
/// A [`NetworkBehaviour`] defines the behaviour of the local node on the network.
|
||||
///
|
||||
/// This trait has been designed to be composable. Multiple implementations can be combined into
|
||||
/// one that handles all the behaviours at once.
|
||||
/// In contrast to [`Transport`](libp2p_core::Transport) which defines **how** to send bytes on the
|
||||
/// network, [`NetworkBehaviour`] defines **what** bytes to send and **to whom**.
|
||||
///
|
||||
/// # Deriving `NetworkBehaviour`
|
||||
/// Each protocol (e.g. `libp2p-ping`, `libp2p-identify` or `libp2p-kad`) implements
|
||||
/// [`NetworkBehaviour`]. Multiple implementations of [`NetworkBehaviour`] can be composed into a
|
||||
/// hierarchy of [`NetworkBehaviour`]s where parent implementations delegate to child
|
||||
/// implementations. Finally the root of the [`NetworkBehaviour`] hierarchy is passed to
|
||||
/// [`Swarm`](crate::Swarm) where it can then control the behaviour of the local node on a libp2p
|
||||
/// network.
|
||||
///
|
||||
/// Crate users can implement this trait by using the the `#[derive(NetworkBehaviour)]`
|
||||
/// # Hierarchy of [`NetworkBehaviour`]
|
||||
///
|
||||
/// To compose multiple [`NetworkBehaviour`] implementations into a single [`NetworkBehaviour`]
|
||||
/// implementation, potentially building a multi-level hierarchy of [`NetworkBehaviour`]s, one can
|
||||
/// use one of the [`NetworkBehaviour`] combinators, and/or use the [`NetworkBehaviour`] derive
|
||||
/// macro.
|
||||
///
|
||||
/// ## Combinators
|
||||
///
|
||||
/// [`NetworkBehaviour`] combinators wrap one or more [`NetworkBehaviour`] implementations and
|
||||
/// implement [`NetworkBehaviour`] themselves. Example is the [`Toggle`](crate::toggle::Toggle)
|
||||
/// [`NetworkBehaviour`].
|
||||
///
|
||||
/// ``` rust
|
||||
/// # use libp2p_swarm::DummyBehaviour;
|
||||
/// # use libp2p_swarm::toggle::Toggle;
|
||||
/// let my_behaviour = DummyBehaviour::default();
|
||||
/// let my_toggled_behaviour = Toggle::from(Some(my_behaviour));
|
||||
/// ```
|
||||
///
|
||||
/// ## Derive Macro
|
||||
///
|
||||
/// One can derive [`NetworkBehaviour`] for a custom `struct` via the `#[derive(NetworkBehaviour)]`
|
||||
/// proc macro re-exported by the `libp2p` crate. The macro generates a delegating `trait`
|
||||
/// implementation for the `struct`, which delegates method calls to all struct members.
|
||||
///
|
||||
/// Struct members that don't implement [`NetworkBehaviour`] must be annotated with `#[behaviour(ignore)]`.
|
||||
/// implementation for the custom `struct`. Each [`NetworkBehaviour`] trait method is simply
|
||||
/// delegated to each `struct` member in the order the `struct` is defined. For example for
|
||||
/// [`NetworkBehaviour::poll`] it will first poll the first `struct` member until it returns
|
||||
/// [`Poll::Pending`] before moving on to later members. For [`NetworkBehaviour::addresses_of_peer`]
|
||||
/// it will delegate to each `struct` member and return a concatenated array of all addresses
|
||||
/// returned by the struct members.
|
||||
///
|
||||
/// By default the derive sets the [`NetworkBehaviour::OutEvent`] as `()` but this can be overridden
|
||||
/// with `#[behaviour(out_event = "AnotherType")]`.
|
||||
@ -50,7 +80,72 @@ type THandlerInEvent<THandler> =
|
||||
/// When setting a custom `out_event` users have to implement [`From`] converting from each of the
|
||||
/// event types generated by the struct members to the custom `out_event`.
|
||||
///
|
||||
/// Alternatively, users can specify `#[behaviour(event_process = true)]`. Events generated by the
|
||||
/// ``` rust
|
||||
/// # use libp2p::identify::{Identify, IdentifyEvent};
|
||||
/// # use libp2p::ping::{Ping, PingEvent};
|
||||
/// # use libp2p::NetworkBehaviour;
|
||||
/// #[derive(NetworkBehaviour)]
|
||||
/// #[behaviour(out_event = "Event")]
|
||||
/// struct MyBehaviour {
|
||||
/// identify: Identify,
|
||||
/// ping: Ping,
|
||||
/// }
|
||||
///
|
||||
/// enum Event {
|
||||
/// Identify(IdentifyEvent),
|
||||
/// Ping(PingEvent),
|
||||
/// }
|
||||
///
|
||||
/// impl From<IdentifyEvent> for Event {
|
||||
/// fn from(event: IdentifyEvent) -> Self {
|
||||
/// Self::Identify(event)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl From<PingEvent> for Event {
|
||||
/// fn from(event: PingEvent) -> Self {
|
||||
/// Self::Ping(event)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Struct members that don't implement [`NetworkBehaviour`] must be annotated with
|
||||
/// `#[behaviour(ignore)]`.
|
||||
///
|
||||
/// ``` rust
|
||||
/// # use libp2p::identify::{Identify, IdentifyEvent};
|
||||
/// # use libp2p::ping::{Ping, PingEvent};
|
||||
/// # use libp2p::NetworkBehaviour;
|
||||
/// #[derive(NetworkBehaviour)]
|
||||
/// #[behaviour(out_event = "Event")]
|
||||
/// struct MyBehaviour {
|
||||
/// identify: Identify,
|
||||
/// ping: Ping,
|
||||
///
|
||||
/// #[behaviour(ignore)]
|
||||
/// some_string: String,
|
||||
/// }
|
||||
/// #
|
||||
/// # enum Event {
|
||||
/// # Identify(IdentifyEvent),
|
||||
/// # Ping(PingEvent),
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl From<IdentifyEvent> for Event {
|
||||
/// # fn from(event: IdentifyEvent) -> Self {
|
||||
/// # Self::Identify(event)
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl From<PingEvent> for Event {
|
||||
/// # fn from(event: PingEvent) -> Self {
|
||||
/// # Self::Ping(event)
|
||||
/// # }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// For users that need access to the root [`NetworkBehaviour`] implementation while processing
|
||||
/// emitted events, one can specify `#[behaviour(event_process = true)]`. Events generated by the
|
||||
/// struct members are delegated to [`NetworkBehaviourEventProcess`] implementations. Those must be
|
||||
/// provided by the user on the type that [`NetworkBehaviour`] is derived on.
|
||||
///
|
||||
|
Reference in New Issue
Block a user