-
Notifications
You must be signed in to change notification settings - Fork 949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(swarm): Add AndBehaviour #3366
Conversation
Hmm, I think the fix is worth landing (maybe even in a separate PR?). If |
32d2f44
to
e8d6e00
Compare
fff9e31
to
910f7c7
Compare
for generic types when out_event was not provided. Previously The enum generated didn't have the NetworkBehaviour impl constraints whilst using the generics for <Generic>::OutEvent.
instead of a custom structure that derives `NetworkBehaviour`.
Good question! So it seems a matter of choosing where to have more complexity, either in the code (manually implementation) or in the user API, |
This pull request has merge conflicts. Could you please resolve them @jxs? 🙏 |
My vote would go against providing an |
This pull request has merge conflicts. Could you please resolve them @jxs? 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still in favor of adding an And
NetworkBehaviour
, even though it is very simple. Not a strong opinion.
Can you please extract the swarm-derive
fix into a separate pull request @jxs?
swarm-derive/CHANGELOG.md
Outdated
@@ -1,9 +1,14 @@ | |||
# 0.32.0 [unreleased] | |||
|
|||
- Fix `NetworkBehaviour` Derive macro for generic types when `out_event` was not provided. Previously The enum generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Fix `NetworkBehaviour` Derive macro for generic types when `out_event` was not provided. Previously The enum generated | |
- Fix `NetworkBehaviour` Derive macro for generic types when `out_event` was not provided. Previously the enum generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Max, addressed in #3393
swarm/CHANGELOG.md
Outdated
@@ -1,5 +1,10 @@ | |||
# 0.42.0 [unreleased] | |||
|
|||
- Add `And` struct that combines two `NetworkBehaviour` implementations. Helfpful for when one wants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Add `And` struct that combines two `NetworkBehaviour` implementations. Helfpful for when one wants | |
- Add `And` struct that combines two `NetworkBehaviour` implementations. Helpful for when one wants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks! updated!
swarm/src/behaviour.rs
Outdated
/// Implementation of [`NetworkBehaviour`] that combines two underlying implementations. | ||
#[cfg(feature = "macros")] | ||
#[derive(Debug, Default, libp2p_swarm_derive::NetworkBehaviour)] | ||
#[behaviour(prelude = "crate::derive_prelude")] | ||
pub struct And<A, B> { | ||
first: A, | ||
second: B, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NetworkBehaviour
combinators like Toggle
and Either
are in their own file. I would suggest doing the same for And
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Addressed!
If we add it, I think the fields should just be public to make access easier. |
swarm/src/behaviour.rs
Outdated
@@ -40,6 +41,47 @@ pub(crate) type THandlerInEvent<THandler> = | |||
pub(crate) type THandlerOutEvent<THandler> = | |||
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent; | |||
|
|||
/// Implementation of [`NetworkBehaviour`] that combines two underlying implementations. | |||
#[cfg(feature = "macros")] | |||
#[derive(Debug, Default, libp2p_swarm_derive::NetworkBehaviour)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now this will have the macro-generated OutEvent
looking kinda like this:
enum AndEvent<A, B> {
First(A)
Second(B)
}
What do you think about specifying Either<A, B>
as out-event instead? Would also be more consistent with all of our other "combinators".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Note @jxs that you can still achieve the above suggestion with the derive macro by using the out_event
derive parameter, see https://docs.rs/libp2p-swarm/latest/libp2p_swarm/behaviour/trait.NetworkBehaviour.html#custom-networkbehaviour-with-the-derive-macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I tried that while experimenting, but when you specify a custom out_event
one has to impl From
for each subvariant. In case of using Either
the generated code is the following:
impl<A, B> crate::derive_prelude::NetworkBehaviour for And<A, B>
where
A: crate::derive_prelude::NetworkBehaviour,
B: crate::derive_prelude::NetworkBehaviour,
Either<A, B>: From<<A as crate::derive_prelude::NetworkBehaviour>::OutEvent>,
Either<A, B>: From<<B as crate::derive_prelude::NetworkBehaviour>::OutEvent>,
which kinda doesn't make sense as it would require for us to know A
and B
, and means that specifying out_event
for a derived NetworkBehaviour
with generics is not supported now. Thanks for referring that Elena. I am kind of out of ideas to allow derive
to support custom out_event
for generic structures. Do you ave any suggestion? Else I can add this to the doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yes you're right. Using Either
as out-event would only be possible if we manually derive NetworkBehaviour
. I don't feel strongly about it, thus I'm fine with sticking with the current solution.
I am kind of out of ideas to allow derive to support custom out_event for generic structures. Do you ave any suggestion?
I don't think its possible. We will always run into the issue of conflicting implementations if we try to auto-implement From
, since A and B theoretically may have the same type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a point for not providing an And
behaviour. If a user wants to group a set of NetworkBehaviour
s together, they can do so themselves and provide a more meaningful name than And
. Like, if they combine certain behaviours together than are only available to under a "legacy" feature-toggle, they can call this behaviour Legacy
and the generated name will make more sense.
Plus, they can add as many behaviours as they want, not just two, they can decide on the visibility, they can decide on the names etc.
I really don't see the value in providing an And
behaviour.
Opened #3393
``
Yeah, it's the dilemma regarding being allowed to make changes without breaking API easily vs easier to access API, funny enough I thought you'd go for the first 😁 Updated! |
meanwhile opened #3393 but forgot to open it from a libp2p/rust-libp2p repo so we could then make this one target it sorry. After that one gets merged this one will be updated. |
use ReadyUpgrade for Handler::InboundProtocol
use ReadyUpgrade for Handler::OutboundProtocol.
This pull request has merge conflicts. Could you please resolve them @jxs? 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am against adding this. See discussion: #3366 (comment).
This pull request has merge conflicts. Could you please resolve them @jxs? 🙏 |
Description
Addresses #2719.
Notes
I started this by basically following the code generated by a
NetworkBehaviour
derive implementation for a struct similar toAnd
(but without generic fields) but then it seemed a lot of similar code to the generated macro to maintain.I then followed to the approach submitted on this PR, have the
And
struct itself theNetworkBehaviour
derived. While going for this approach I found a bug with theNetworkBehaviour
derive implementation for generics, whenout_event
was not provided the enum generated missed theNetworkBehaviour
impl constraint for the generic variants whilst using the generics for<Generic>::OutEvent
. This is what a4570af addresses.The manual
Debug
implementation was required because theDebug
derive is not smart enough, when we annotate it on a struct with generics it requires it's generics to implDebug
but on our case what we want is that only theOutEvent
associated type of the generic variants implementDebug
. see similar here or hereThe derive macro shouldn't be breaking, from what I tested the printed debug output is the same for non generic types.
I updated the ping example to use
And
, if agreed will update the other examples.If this seems to hacky I can rollback and submit instead the first approach.
Links to any relevant issues
Open Questions
Change checklist