-
Notifications
You must be signed in to change notification settings - Fork 964
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
Allow users to opt out of the NetworkBehaviourEventProcess
mechanism
#1630
Conversation
This matches what I've been thinking about for rust-ipfs quite well. I was planning to try just implementing NetworkBehaviour directly but of course it would nicer if this way was supported, perhaps as an off-by-default option in the derive?
Related to this we have a ... bit ... ugly way of looping around polling everything, including the swarm in non-async context. If one were to use |
The problem we ran into with select! is that you get mutability borrow checker issues if you want to use the I am not sure what a really good solution to this looks like. One I was thinking of is: Select all the futures in the loop with the |
I don't know about |
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.
The PR looks good.
I'm not a fan of the attribute name "bubble_up_events"
, but I can't come up with anything better.
Maybe I misunderstood the problem then, I thought that could be design not be fixable 🤔 We had something along these lines: let mut swarm = todo!();
let mut some_other_component = todo!();
loop {
futures::select! {
// swarm.next requires &mut self
swarm_event = swarm.next() => {
dbg!(swarm_event);
}
other_event = some_other_component.next() => {
// `react_to_event` also requires &mut self
swarm.react_to_event(other_event) // mutability lifetime error here because of 2nd mutable binding to `swarm`
}
}
} My understanding is, that you can't fix that unless you drop the future returned from
I am very eager to learn more about this! Can you point to some code please?
I will try and think of something better! |
That is true, but the macro does make sure that this future gets dropped if you enter the |
That is interesting, I will have to play around with this a bit more then to see if I can get it working. Thanks! By the way, I've thought of some different names for the flag introduced in this PR:
We could also introduce an enum parameter "events" (or "handle_events"): #[behaviour(events = "process_locally")
#[behaviour(events = "forward_to_swarm") |
88c16fd
to
f8ea37e
Compare
swarm.next()
NetworkBehaviourEventProcess
mechanism
f8ea37e
to
80b2abf
Compare
@tomaka I rolled with I tried to correctly set inter-doc links and the only way I got it working was through the |
03d0911
to
a2d82e4
Compare
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.
Ad intra-doc-links: Is the problem simply that core-derive
has no dependency on libp2p-swarm
? If so, am I the only one thinking that even if it is technically not necessary to have a libp2p-swarm
dependency in order for it to compile, core-derive
should declare one since it provides a macro for libp2p-swarm
and depends on a specific API version of that crate? I would then hope that intra-rustdoc-links work and also the included test(s) run against the version specified as a dependency and so check for compatibility.
Ad bubbling up events: Another attribute name suggestion would be event_delegate
, defaulting to false
. Essentially !delegate = process
. I have no strong preferences there though.
Not quite. The problem I was referring to was that I couldn't make intra-doc links in the form of "crate::NetworkBehaviour" work for both, the libp2p-swarm crate and the libp2p crate.
I am not attached to |
That sounds a bit like rust-lang/rust#65983 (context rust-lang/rust#43466). I personally would prefer we stick to intra-rustdoc-links, even if there are still issues, to avoid mixing different styles of links in this project and because with the other type of links we never get any warning about dead links. |
I am happy to change them. In which docs should they work, |
If rust-lang/rust#65983 is the cause, then |
a2d82e4
to
9fe2b65
Compare
@romanb Updated! All the docs I touched use intra-doc links now :) |
9fe2b65
to
bfb3815
Compare
Since this seems to be a backward-compatible addition, I'm inclined to cut a release of |
Putting this up as a PoC to spark discussion. Happy to change the name of the attribute if someone can come up with something better 😅
The idea is the following:
Previously, we used the
libp2p::Swarm
by putting all dependencies that need to react to events from the network into the top-level NetworkBehaviour and put the relevant code into theinject_event
callbacks.I've always found this a bit awkward. Having to put things into the
NetworkBehaviour
even though they are not really part of the "network stack" of an application doesn't feel "right".So I've been thinking about an alternative approach and came up with this:
Basically, the
Swarm
is part of a bigger loop and events are bubbled all the way and distributed to other components in the application.If the main components of the application are structured around such a polling mechanism, this works really nicely. All components can just be
mut
able and distribute events to each other without any further locking mechanism.This PR extends the custom derive to make this usage easier by not requiring the implementation of
NetworkBehaviourEventProcess
but instead, converts every event into the specificedOutEvent
and bubbles it up all the way.This is already possible by simply saving all events inside the
inject_event
function and having a custompoll
function that emits them again. This PR just makes this pattern easier to use.Thoughts?
Is there a reason I am missing that makes this usage of rust-libp2p a really bad idea?
The only thing I could think of is starvation of the loop if there is little network activity but I think that can be solved in an acceptable way by using a
timeout
on theswarm.next()
future.