mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-04-25 03:02:12 +00:00
Enhance NetworkBehaviour docs (#1362)
* add docs about deriving NetworkBehaviour * add commentary to the chat example also minor stuff like reordering to match the struct elements, note why the listening address is reported in poll. * fix remove the warning on the example ignored field * Apply suggestions from code review Thanks for suggestions! Co-Authored-By: Max Inden <mail@max-inden.de> * chore cleanup added docs after suggestions * fix print all listening addresses in examples/chat not that there should be more than one but it makes sense to repeat the full example here. * chore remove confusing writing on printing the listening addrs * fix use intra-docs, spelling Co-Authored-By: Roman S. Borschel <roman@parity.io> Co-authored-by: Max Inden <mail@max-inden.de> Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
This commit is contained in:
parent
3f968cbf92
commit
7df3e74d79
@ -79,13 +79,30 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
// We create a custom network behaviour that combines floodsub and mDNS.
|
||||
// In the future, we want to improve libp2p to make this easier to do.
|
||||
// Use the derive to generate delegating NetworkBehaviour impl and require the
|
||||
// NetworkBehaviourEventProcess implementations below.
|
||||
#[derive(NetworkBehaviour)]
|
||||
struct MyBehaviour<TSubstream: AsyncRead + AsyncWrite> {
|
||||
floodsub: Floodsub<TSubstream>,
|
||||
mdns: Mdns<TSubstream>,
|
||||
|
||||
// Struct fields which do not implement NetworkBehaviour need to be ignored
|
||||
#[behaviour(ignore)]
|
||||
#[allow(dead_code)]
|
||||
ignored_member: bool,
|
||||
}
|
||||
|
||||
impl<TSubstream: AsyncRead + AsyncWrite> NetworkBehaviourEventProcess<FloodsubEvent> for MyBehaviour<TSubstream> {
|
||||
// Called when `floodsub` produces an event.
|
||||
fn inject_event(&mut self, message: FloodsubEvent) {
|
||||
if let FloodsubEvent::Message(message) = message {
|
||||
println!("Received: '{:?}' from {:?}", String::from_utf8_lossy(&message.data), message.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream: AsyncRead + AsyncWrite> NetworkBehaviourEventProcess<MdnsEvent> for MyBehaviour<TSubstream> {
|
||||
// Called when `mdns` produces an event.
|
||||
fn inject_event(&mut self, event: MdnsEvent) {
|
||||
match event {
|
||||
MdnsEvent::Discovered(list) =>
|
||||
@ -102,21 +119,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream: AsyncRead + AsyncWrite> NetworkBehaviourEventProcess<FloodsubEvent> for MyBehaviour<TSubstream> {
|
||||
// Called when `floodsub` produces an event.
|
||||
fn inject_event(&mut self, message: FloodsubEvent) {
|
||||
if let FloodsubEvent::Message(message) = message {
|
||||
println!("Received: '{:?}' from {:?}", String::from_utf8_lossy(&message.data), message.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a Swarm to manage peers and events
|
||||
let mut swarm = {
|
||||
let mdns = task::block_on(Mdns::new())?;
|
||||
let mut behaviour = MyBehaviour {
|
||||
floodsub: Floodsub::new(local_peer_id.clone()),
|
||||
mdns
|
||||
mdns,
|
||||
ignored_member: false,
|
||||
};
|
||||
|
||||
behaviour.floodsub.subscribe(floodsub_topic.clone());
|
||||
@ -152,8 +161,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
Poll::Ready(None) => return Poll::Ready(Ok(())),
|
||||
Poll::Pending => {
|
||||
if !listening {
|
||||
if let Some(a) = Swarm::listeners(&swarm).next() {
|
||||
println!("Listening on {:?}", a);
|
||||
for addr in Swarm::listeners(&swarm) {
|
||||
println!("Listening on {:?}", addr);
|
||||
listening = true;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ use quote::quote;
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, DeriveInput, Data, DataStruct, Ident};
|
||||
|
||||
/// The interface that satisfies Rust.
|
||||
/// Generates a delegating `NetworkBehaviour` implementation for the struct this is used for. See
|
||||
/// the trait documentation for better description.
|
||||
#[proc_macro_derive(NetworkBehaviour, attributes(behaviour))]
|
||||
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
|
@ -26,6 +26,23 @@ use std::{error, task::Context, task::Poll};
|
||||
///
|
||||
/// This trait has been designed to be composable. Multiple implementations can be combined into
|
||||
/// one that handles all the behaviours at once.
|
||||
///
|
||||
/// # Deriving `NetworkBehaviour`
|
||||
///
|
||||
/// Crate users can implement this trait by using the 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 trait members. Any events
|
||||
/// generated by struct members are delegated to [`NetworkBehaviourEventProcess`] implementations
|
||||
/// which are expected to be provided by the user.
|
||||
///
|
||||
/// Optionally one can implement a custom `poll` function, which needs to be tagged with the
|
||||
/// `#[behaviour(poll_method = "poll")]` attribute, and would be called last with no parameters.
|
||||
///
|
||||
/// By default the derive sets the `NetworkBehaviour::OutEvent` as `()` but this can be overriden
|
||||
/// with `#[behaviour(out_event = "AnotherType")]`.
|
||||
///
|
||||
/// `#[behaviour(ignore)]` can be added on a struct field to disable generation of delegation to
|
||||
/// the fields which do not implement `NetworkBehaviour`.
|
||||
pub trait NetworkBehaviour {
|
||||
/// Handler for all the protocols the network behaviour supports.
|
||||
type ProtocolsHandler: IntoProtocolsHandler;
|
||||
@ -163,9 +180,8 @@ pub trait PollParameters {
|
||||
fn local_peer_id(&self) -> &PeerId;
|
||||
}
|
||||
|
||||
/// Used when deriving `NetworkBehaviour`. When deriving `NetworkBehaviour`, must be implemented
|
||||
/// for all the possible event types generated by the various fields.
|
||||
// TODO: document how the custom behaviour works and link this here
|
||||
/// When deriving [`NetworkBehaviour`] this trait must be implemented for all the possible event types
|
||||
/// generated by the inner behaviours.
|
||||
pub trait NetworkBehaviourEventProcess<TEvent> {
|
||||
/// Called when one of the fields of the type you're deriving `NetworkBehaviour` on generates
|
||||
/// an event.
|
||||
|
Loading…
x
Reference in New Issue
Block a user