mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-04-25 11:02:12 +00:00
Allow users to opt out of the NetworkBehaviourEventProcess
mechanism (#1630)
* Allow users to opt-out of the NetworkBehaviourEventProcess mechanism * Add CHANGELOG entry * Prepare release. Co-authored-by: Roman Borschel <romanb@users.noreply.github.com> Co-authored-by: Roman S. Borschel <roman@parity.io>
This commit is contained in:
parent
d645ccb0df
commit
c4a5497d2d
@ -21,6 +21,7 @@
|
|||||||
- [`libp2p-yamux` CHANGELOG](muxers/yamux/CHANGELOG.md)
|
- [`libp2p-yamux` CHANGELOG](muxers/yamux/CHANGELOG.md)
|
||||||
- [`multistream-select` CHANGELOG](misc/multistream-select/CHANGELOG.md)
|
- [`multistream-select` CHANGELOG](misc/multistream-select/CHANGELOG.md)
|
||||||
- [`parity-multiaddr` CHANGELOG](misc/multiaddr/CHANGELOG.md)
|
- [`parity-multiaddr` CHANGELOG](misc/multiaddr/CHANGELOG.md)
|
||||||
|
- [`libp2p-core-derive` CHANGELOG](misc/core-derive/CHANGELOG.md)
|
||||||
|
|
||||||
# Version 0.21.1 (2020-07-02)
|
# Version 0.21.1 (2020-07-02)
|
||||||
|
|
||||||
|
6
misc/core-derive/CHANGELOG.md
Normal file
6
misc/core-derive/CHANGELOG.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# 0.20.1 [2020-07-08]
|
||||||
|
|
||||||
|
- Allow users to opt out of the `NetworkBehaviourEventProcess`
|
||||||
|
mechanism through `#[behaviour(event_process = false)]`. This is
|
||||||
|
useful if users want to process all events while polling the
|
||||||
|
swarm through `SwarmEvent::Behaviour`.
|
@ -2,7 +2,7 @@
|
|||||||
name = "libp2p-core-derive"
|
name = "libp2p-core-derive"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Procedural macros of libp2p-core"
|
description = "Procedural macros of libp2p-core"
|
||||||
version = "0.20.0"
|
version = "0.20.1"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
|
@ -70,28 +70,24 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
quote!{<#(#lf,)* #(#tp,)* #(#cst,)*>}
|
quote!{<#(#lf,)* #(#tp,)* #(#cst,)*>}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the `where ...` clause of the trait implementation.
|
// Whether or not we require the `NetworkBehaviourEventProcess` trait to be implemented.
|
||||||
let where_clause = {
|
let event_process = {
|
||||||
let additional = data_struct.fields.iter()
|
let mut event_process = true; // Default to true for backwards compatibility
|
||||||
.filter(|x| !is_ignored(x))
|
|
||||||
.flat_map(|field| {
|
|
||||||
let ty = &field.ty;
|
|
||||||
vec![
|
|
||||||
quote!{#ty: #trait_to_impl},
|
|
||||||
quote!{Self: #net_behv_event_proc<<#ty as #trait_to_impl>::OutEvent>},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if let Some(where_clause) = where_clause {
|
for meta_items in ast.attrs.iter().filter_map(get_meta_items) {
|
||||||
if where_clause.predicates.trailing_punct() {
|
for meta_item in meta_items {
|
||||||
Some(quote!{#where_clause #(#additional),*})
|
match meta_item {
|
||||||
} else {
|
syn::NestedMeta::Meta(syn::Meta::NameValue(ref m)) if m.path.is_ident("event_process") => {
|
||||||
Some(quote!{#where_clause, #(#additional),*})
|
if let syn::Lit::Bool(ref b) = m.lit {
|
||||||
|
event_process = b.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Some(quote!{where #(#additional),*})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event_process
|
||||||
};
|
};
|
||||||
|
|
||||||
// The final out event.
|
// The final out event.
|
||||||
@ -115,6 +111,34 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
out
|
out
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Build the `where ...` clause of the trait implementation.
|
||||||
|
let where_clause = {
|
||||||
|
let additional = data_struct.fields.iter()
|
||||||
|
.filter(|x| !is_ignored(x))
|
||||||
|
.flat_map(|field| {
|
||||||
|
let ty = &field.ty;
|
||||||
|
vec![
|
||||||
|
quote!{#ty: #trait_to_impl},
|
||||||
|
if event_process {
|
||||||
|
quote!{Self: #net_behv_event_proc<<#ty as #trait_to_impl>::OutEvent>}
|
||||||
|
} else {
|
||||||
|
quote!{#out_event: From< <#ty as #trait_to_impl>::OutEvent >}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if let Some(where_clause) = where_clause {
|
||||||
|
if where_clause.predicates.trailing_punct() {
|
||||||
|
Some(quote!{#where_clause #(#additional),*})
|
||||||
|
} else {
|
||||||
|
Some(quote!{#where_clause, #(#additional),*})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(quote!{where #(#additional),*})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Build the list of statements to put in the body of `addresses_of_peer()`.
|
// Build the list of statements to put in the body of `addresses_of_peer()`.
|
||||||
let addresses_of_peer_stmts = {
|
let addresses_of_peer_stmts = {
|
||||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||||
@ -395,12 +419,24 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
wrapped_event = quote!{ #either_ident::First(#wrapped_event) };
|
wrapped_event = quote!{ #either_ident::First(#wrapped_event) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let generate_event_match_arm = if event_process {
|
||||||
|
quote! {
|
||||||
|
std::task::Poll::Ready(#network_behaviour_action::GenerateEvent(event)) => {
|
||||||
|
#net_behv_event_proc::inject_event(self, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
std::task::Poll::Ready(#network_behaviour_action::GenerateEvent(event)) => {
|
||||||
|
return std::task::Poll::Ready(#network_behaviour_action::GenerateEvent(event.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Some(quote!{
|
Some(quote!{
|
||||||
loop {
|
loop {
|
||||||
match #field_name.poll(cx, poll_params) {
|
match #field_name.poll(cx, poll_params) {
|
||||||
std::task::Poll::Ready(#network_behaviour_action::GenerateEvent(event)) => {
|
#generate_event_match_arm
|
||||||
#net_behv_event_proc::inject_event(self, event)
|
|
||||||
}
|
|
||||||
std::task::Poll::Ready(#network_behaviour_action::DialAddress { address }) => {
|
std::task::Poll::Ready(#network_behaviour_action::DialAddress { address }) => {
|
||||||
return std::task::Poll::Ready(#network_behaviour_action::DialAddress { address });
|
return std::task::Poll::Ready(#network_behaviour_action::DialAddress { address });
|
||||||
}
|
}
|
||||||
|
@ -263,3 +263,46 @@ fn nested_derives_with_import() {
|
|||||||
require_net_behaviour::<Bar>();
|
require_net_behaviour::<Bar>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn event_process_false() {
|
||||||
|
enum BehaviourOutEvent {
|
||||||
|
Ping(libp2p::ping::PingEvent),
|
||||||
|
Identify(libp2p::identify::IdentifyEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<libp2p::ping::PingEvent> for BehaviourOutEvent {
|
||||||
|
fn from(event: libp2p::ping::PingEvent) -> Self {
|
||||||
|
BehaviourOutEvent::Ping(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<libp2p::identify::IdentifyEvent> for BehaviourOutEvent {
|
||||||
|
fn from(event: libp2p::identify::IdentifyEvent) -> Self {
|
||||||
|
BehaviourOutEvent::Identify(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(NetworkBehaviour)]
|
||||||
|
#[behaviour(out_event = "BehaviourOutEvent", event_process = false)]
|
||||||
|
struct Foo {
|
||||||
|
ping: libp2p::ping::Ping,
|
||||||
|
identify: libp2p::identify::Identify,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn bar() {
|
||||||
|
require_net_behaviour::<Foo>();
|
||||||
|
|
||||||
|
let mut swarm: libp2p::Swarm<Foo> = unimplemented!();
|
||||||
|
|
||||||
|
// check that the event is bubbled up all the way to swarm
|
||||||
|
let _ = async {
|
||||||
|
match swarm.next().await {
|
||||||
|
BehaviourOutEvent::Ping(_) => {},
|
||||||
|
BehaviourOutEvent::Identify(_) => {},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.20.1 [2020-07-08]
|
||||||
|
|
||||||
|
- Documentation updates.
|
||||||
|
|
||||||
# 0.20.0 [2020-07-01]
|
# 0.20.0 [2020-07-01]
|
||||||
|
|
||||||
- Updated the `libp2p-core` dependency.
|
- Updated the `libp2p-core` dependency.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "libp2p-swarm"
|
name = "libp2p-swarm"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "The libp2p swarm"
|
description = "The libp2p swarm"
|
||||||
version = "0.20.0"
|
version = "0.20.1"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/libp2p/rust-libp2p"
|
repository = "https://github.com/libp2p/rust-libp2p"
|
||||||
|
@ -31,18 +31,27 @@ use std::{error, task::Context, task::Poll};
|
|||||||
///
|
///
|
||||||
/// Crate users can implement this trait by using the the `#[derive(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`
|
/// 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
|
/// implementation for the `struct`, which delegates method calls to all trait members.
|
||||||
/// 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
|
/// By default the derive sets the [`NetworkBehaviour::OutEvent`] as `()` but this can be overridden
|
||||||
/// `#[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")]`.
|
/// with `#[behaviour(out_event = "AnotherType")]`.
|
||||||
///
|
///
|
||||||
/// `#[behaviour(ignore)]` can be added on a struct field to disable generation of delegation to
|
/// Struct members that don't implement [`NetworkBehaviour`] must be annotated with `#[behaviour(ignore)]`.
|
||||||
/// the fields which do not implement `NetworkBehaviour`.
|
///
|
||||||
|
/// By default, events generated by the remaining members are delegated to [`NetworkBehaviourEventProcess`]
|
||||||
|
/// implementations. Those must be provided by the user on the type that [`NetworkBehaviour`] is
|
||||||
|
/// derived on.
|
||||||
|
///
|
||||||
|
/// Alternatively, users can specify `#[behaviour(event_process = false)]`. In this case, users
|
||||||
|
/// should provide a custom `out_event` and implement [`From`] for each of the event types generated
|
||||||
|
/// by the struct members.
|
||||||
|
/// Not processing events within the derived [`NetworkBehaviour`] will cause them to be emitted as
|
||||||
|
/// part of polling the swarm in [`SwarmEvent::Behaviour`](crate::SwarmEvent::Behaviour).
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
pub trait NetworkBehaviour: Send + 'static {
|
pub trait NetworkBehaviour: Send + 'static {
|
||||||
/// Handler for all the protocols the network behaviour supports.
|
/// Handler for all the protocols the network behaviour supports.
|
||||||
type ProtocolsHandler: IntoProtocolsHandler;
|
type ProtocolsHandler: IntoProtocolsHandler;
|
||||||
@ -193,8 +202,11 @@ pub trait PollParameters {
|
|||||||
fn local_peer_id(&self) -> &PeerId;
|
fn local_peer_id(&self) -> &PeerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When deriving [`NetworkBehaviour`] this trait must be implemented for all the possible event types
|
/// When deriving [`NetworkBehaviour`] this trait must by default be implemented for all the
|
||||||
/// generated by the inner behaviours.
|
/// possible event types generated by the inner behaviours.
|
||||||
|
///
|
||||||
|
/// You can opt out of this behaviour through `#[behaviour(event_process = false)]`. See the
|
||||||
|
/// documentation of [`NetworkBehaviour`] for details.
|
||||||
pub trait NetworkBehaviourEventProcess<TEvent> {
|
pub trait NetworkBehaviourEventProcess<TEvent> {
|
||||||
/// Called when one of the fields of the type you're deriving `NetworkBehaviour` on generates
|
/// Called when one of the fields of the type you're deriving `NetworkBehaviour` on generates
|
||||||
/// an event.
|
/// an event.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user