diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 6e2a163c..65d6817c 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -69,7 +69,7 @@ pub(crate) type THandlerOutEvent = /// let my_toggled_behaviour = Toggle::from(Some(my_behaviour)); /// ``` /// -/// ## Derive Macro +/// ## Custom [`NetworkBehaviour`] with the 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` @@ -80,11 +80,20 @@ pub(crate) type THandlerOutEvent = /// 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")]`. +/// When creating a custom [`NetworkBehaviour`], you must choose one of two methods to respond to +/// incoming events: +/// * One option is setting a custom `out_event` with `#[behaviour(out_event = "AnotherType")]`. +/// In this case, events generated by the custom [`NetworkBehaviour`] struct members will be +/// converted to your custom `out_event` for you to handle after polling the swarm. +/// * Alternatively, users that need access to the root [`NetworkBehaviour`] implementation while +/// processing emitted events, can specify `#[behaviour(event_process = true)]` (default is false). +/// Events generated by the behaviour's struct members are delegated to [`NetworkBehaviourEventProcess`] +/// trait implementations. Those must be provided by the user on the type that [`NetworkBehaviour`] +/// is derived on. /// -/// 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`. +/// When setting a custom `out_event`, the aforementioned conversion of each of the event types +/// generated by the struct members to the custom `out_event` is handled by [`From`] +/// implementations the user needs to provide. /// /// ``` rust /// # use libp2p::identify::{Identify, IdentifyEvent}; @@ -115,6 +124,18 @@ pub(crate) type THandlerOutEvent = /// } /// ``` /// +/// When using `event_process = true` the [`NetworkBehaviourEventProcess`] trait implementations +/// are granted exclusive access to the [`NetworkBehaviour`], therefore +/// [blocking code](https://ryhl.io/blog/async-what-is-blocking/) in these implementations will +/// block the entire [`Swarm`](crate::Swarm) from processing new events, since the swarm cannot progress +/// without also having exclusive access to the [`NetworkBehaviour`]. A better alternative is to execute +/// blocking or asynchronous logic on a separate task, perhaps with the help of a bounded channel to +/// maintain backpressure. The sender for the channel could be included in the NetworkBehaviours constructor. +/// +/// Optionally one can provide a custom `poll` function through the `#[behaviour(poll_method = +/// "poll")]` attribute. This function must have the same signature as the [`NetworkBehaviour#poll`] +/// function and will be called last within the generated [`NetworkBehaviour`] implementation. +/// /// Struct members that don't implement [`NetworkBehaviour`] must be annotated with /// `#[behaviour(ignore)]`. ///