Skip to content
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(transport): allow ListenerId to be user-controlled #3567

Merged
merged 34 commits into from
May 14, 2023

Conversation

dariusc93
Copy link
Contributor

@dariusc93 dariusc93 commented Mar 7, 2023

Description

Transport::listen_on is an asynchronous operation. It returns immediately but the actual process of establishing a listening socket happens as part of Transport::poll which will return one or more TransportEvents related to a particular listen_on call.

Currently, listen_on returns a ListenerId which allows the user of the Transport interface to correlate the events with a particular listen_on call. This "user" is the Swarm runtime. Currently, a user of libp2p establishes a new listening socket by talking to the Swarm::listen_on interface and it is not possible to do the same thing via the NetworkBehaviour trait.

Within the NetworkBehaviour trait, we emit commands to the Swarm like ToSwarm::Dial. These commands don't have a "return value" like a synchronous function does and thus, if we were to add a ToSwarm::ListenOn command, it could not receive the ListenerId from the Transport.

To fix this and to be consistent with our coding guidelines we change the interface of Transport::listen_on to require the user to pass in a ListenerId. This will allow us to construct a command in a NetworkBehaviour that remembers this ID which enables precise tracking of which events containing a ListenerId correlate which a particular listen_on command.

This is especially important in the context of listening on wildcard addresses like 0.0.0.0 because we end up binding to multiple network interfaces and thus emit multiple events for a single listen_on call.

Notes

Links to any relevant issues

Open Questions

  1. Should Transport::listen_on return a ListenerId? This PR doesnt have it return it since its redundant now, but not sure if anybody else feel the same way.

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • A changelog entry has been made in the appropriate crates

@thomaseizinger
Copy link
Contributor

Can you run rustfmt? I'll have a look at the code over the next days.

It is a breaking change so we'll likely hold off a bit on merging that to reduce the rate of breaking changes.

@thomaseizinger
Copy link
Contributor

Should Transport::listen_on return a ListenerId? This PR doesnt have it return it since its redundant now, but not sure if anybody else feel the same way.

Agree with that.

Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am in favor of this but it is a breaking change so we can't merge it immediately.

transports/tcp/src/provider/async_io.rs Outdated Show resolved Hide resolved
@thomaseizinger thomaseizinger added this to the v0.52.0 milestone Mar 12, 2023
@thomaseizinger
Copy link
Contributor

Test failure should go away once you update to latest master.

@mergify

This comment was marked as resolved.

Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to move away from random ListenerIds and instead use the same pattern we used for ConnectionIds: a static atomic counter.

transports/quic/src/lib.rs Outdated Show resolved Hide resolved
@@ -54,6 +55,8 @@ pub use self::memory::MemoryTransport;
pub use self::optional::OptionalTransport;
pub use self::upgrade::Upgrade;

static NEXT_LISTENER_ID: AtomicU64 = AtomicU64::new(1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change this to AtomicUsize and use usize in ListenerId instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it really matters, happy to leave it as a u64. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can leave it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding to the above the argument of portability.

PowerPC and MIPS platforms with 32-bit pointers do not have AtomicU64 or AtomicI64 types.

https://doc.rust-lang.org/std/sync/atomic/index.html#portability

Thus slight preference for AtomicUsize from my end. Also consistent with ConnectionId.

@thomaseizinger thomaseizinger changed the title refactor(transport): Provide ListenerId in Transport::listen_on feat(transport): allow ListenerId to be user-controlled May 5, 2023
@thomaseizinger
Copy link
Contributor

Looking forward to this! I updated the PR description to reflect why we are doing this. Once the remaining comments are resolved, I'd also like @mxinden to have a look at this although I do think we are in agreement here.

@thomaseizinger thomaseizinger marked this pull request as ready for review May 6, 2023 07:26
thomaseizinger
thomaseizinger previously approved these changes May 6, 2023
Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the effort!

I would like @mxinden to also review this.

transports/websocket/src/framed.rs Outdated Show resolved Hide resolved
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
@mergify
Copy link

mergify bot commented May 8, 2023

This pull request has merge conflicts. Could you please resolve them @dariusc93? 🙏

mxinden
mxinden previously approved these changes May 14, 2023
Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments. This is good to go from my end. Thank you for the work @dariusc93!

core/CHANGELOG.md Outdated Show resolved Hide resolved
core/CHANGELOG.md Outdated Show resolved Hide resolved
@@ -54,6 +55,8 @@ pub use self::memory::MemoryTransport;
pub use self::optional::OptionalTransport;
pub use self::upgrade::Upgrade;

static NEXT_LISTENER_ID: AtomicU64 = AtomicU64::new(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding to the above the argument of portability.

PowerPC and MIPS platforms with 32-bit pointers do not have AtomicU64 or AtomicI64 types.

https://doc.rust-lang.org/std/sync/atomic/index.html#portability

Thus slight preference for AtomicUsize from my end. Also consistent with ConnectionId.

dariusc93 and others added 3 commits May 14, 2023 04:34
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Max Inden <mail@max-inden.de>
core/CHANGELOG.md Outdated Show resolved Hide resolved
@mergify mergify bot dismissed mxinden’s stale review May 14, 2023 08:57

Approvals have been dismissed because the PR was updated after the send-it label was applied.

@mergify mergify bot merged commit 5b32c8a into libp2p:master May 14, 2023
61 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants