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

protocols/mdns: Allow users to choose between async-io and tokio runtime #2748

Merged
merged 30 commits into from Sep 2, 2022

Conversation

gallegogt
Copy link
Contributor

Problem

When use the Tokio library with mdns module, it is polling every time the UDP socket; causing hight CPU usage.

Solution

When using Tokio library, use the UppSocket provided by the Tokio library instead of the Async-io wrapper.

Breaking Change

After this fix exist two features async-io, tokio for this module, for the general module must be use the features mdns-async-io or mdns-tokio for async-io or tokio libraries

Links to any relevant issues

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

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.

Thanks!

I think the feature itself is worthwhile having but we need to implement it slightly different. Commands like cargo build --all-features should continue to work across the workspace.

protocols/mdns/CHANGELOG.md Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour.rs Outdated Show resolved Hide resolved
@gallegogt
Copy link
Contributor Author

Hi @thomaseizinge, thanks for the feedback, I will check it

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.

Thanks!

I gave this a more in-depth read, please see the inline comments :)

protocols/mdns/Cargo.toml Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/timer.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
@mxinden
Copy link
Member

mxinden commented Jul 11, 2022

Related issue on if-watch used in libp2p-mdns: mxinden/if-watch#21

//CC @dignifiedquire

@mxinden
Copy link
Member

mxinden commented Jul 11, 2022

Thanks @gallegogt for the thorough patch and thanks @thomaseizinger for the detailed reviews!

@mxinden
Copy link
Member

mxinden commented Jul 14, 2022

@gallegogt let us know once this is ready for another review.

@gallegogt
Copy link
Contributor Author

Hi @mxinden it's ready for review

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.

Thanks!

This looks really good now, I've left a couple more comments :)

protocols/mdns/CHANGELOG.md Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/timer.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/timer.rs Show resolved Hide resolved
protocols/mdns/src/behaviour/timer.rs Outdated Show resolved Hide resolved
protocols/mdns/tests/use-tokio.rs Show resolved Hide resolved
src/lib.rs Show resolved Hide resolved
@gallegogt
Copy link
Contributor Author

Hi @mxinden @thomaseizinger it's ready for review

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.

Thank you for incorporating the feedback :)

I think this is close to being mergeable. I made a few comments where we don't seem to be doing quite the same as previously. Please comment if that is on purpose, otherwise I'd prefer to stick to the previous logic.

protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
@thomaseizinger thomaseizinger changed the title fix(protocols/mdns): fix high cpu usage with tokio library protocols/mdns: Allow users to choose between async-io and tokio runtime Jul 18, 2022
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.

This looks good to me. Deferring final review to @thomaseizinger.

Thanks @gallegogt and @thomaseizinger for the solid work here!

examples/chat-tokio.rs Show resolved Hide resolved
protocols/mdns/CHANGELOG.md Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/socket.rs Outdated Show resolved Hide 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.

Thanks!

I've found too more misalignments with the previous version. Thanks for sticking to this :)

protocols/mdns/CHANGELOG.md Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Show resolved Hide resolved
protocols/mdns/src/behaviour/iface.rs Outdated Show resolved Hide 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.

Thanks for implementing all the feedback!

This is ready now :)

@thomaseizinger
Copy link
Contributor

The test_expired_tokio test is failing. Can you look into that @gallegogt?

@gallegogt
Copy link
Contributor Author

gallegogt commented Jul 20, 2022

The test_expired_tokio test is failing. Can you look into that @gallegogt?

I'll check it, but in my test environments work, I will try in other PC.

@thomaseizinger
Copy link
Contributor

The test_expired_tokio test is failing. Can you look into that @gallegogt?

I'll check it, but in my test environments work, I will try in other PC.

It also fails on my local computer. I am running Manjaro Linux.

@gallegogt
Copy link
Contributor Author

gallegogt commented Jul 21, 2022

The test_expired_tokio test is failing. Can you look into that @gallegogt?

I'll check it, but in my test environments work, I will try in other PC.

It also fails on my local computer. I am running Manjaro Linux.

@thomaseizinger , @mxinden
My environment:

ARM

Description:    Ubuntu 18.04.6 LTS
Release:        18.04
Codename:       bionic

rustc 1.62.0 (a8314ef7d 2022-06-27)

image_2022-07-21_105521367

@mxinden
Copy link
Member

mxinden commented Jul 22, 2022

Failing on my machine as well:

➜  cargo test --all-features
    Finished test [unoptimized + debuginfo] target(s) in 0.17s
     Running unittests src/lib.rs (/home/mxinden/code/github.com/libp2p/rust-libp2p/target/debug/deps/libp2p_mdns-aeea3dee3d0f3ca4)

running 5 tests
test behaviour::iface::dns::tests::build_service_discovery_response_correct ... ok
test behaviour::iface::dns::tests::build_query_correct ... ok
test behaviour::iface::dns::tests::test_random_string ... ok
test behaviour::iface::query::tests::test_create_mdns_peer ... ok
test behaviour::iface::dns::tests::build_query_response_correct ... ok

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running tests/use-async-std.rs (/home/mxinden/code/github.com/libp2p/rust-libp2p/target/debug/deps/use_async_std-77e86062dfdf653f)

running 3 tests
test test_discovery_async_std_ipv4 ... ok
test test_discovery_async_std_ipv6 ... ok
test test_expired_async_std ... ok

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.03s

     Running tests/use-tokio.rs (/home/mxinden/code/github.com/libp2p/rust-libp2p/target/debug/deps/use_tokio-278cda36b01406d1)

running 3 tests
test test_expired_tokio ... FAILED
test test_discovery_tokio_ipv4 ... ok
test test_discovery_tokio_ipv6 ... ok

failures:

---- test_expired_tokio stdout ----
thread 'test_expired_tokio' panicked at 'called `Result::unwrap()` on an `Err` value: Elapsed(())', protocols/mdns/tests/use-tokio.rs:55:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    test_expired_tokio

test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.15s

error: test failed, to rerun pass '--test use-tokio'

@gallegogt
Copy link
Contributor Author

Failing on my machine as well:


➜  cargo test --all-features

    Finished test [unoptimized + debuginfo] target(s) in 0.17s

     Running unittests src/lib.rs (/home/mxinden/code/github.com/libp2p/rust-libp2p/target/debug/deps/libp2p_mdns-aeea3dee3d0f3ca4)



running 5 tests

test behaviour::iface::dns::tests::build_service_discovery_response_correct ... ok

test behaviour::iface::dns::tests::build_query_correct ... ok

test behaviour::iface::dns::tests::test_random_string ... ok

test behaviour::iface::query::tests::test_create_mdns_peer ... ok

test behaviour::iface::dns::tests::build_query_response_correct ... ok



test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s



     Running tests/use-async-std.rs (/home/mxinden/code/github.com/libp2p/rust-libp2p/target/debug/deps/use_async_std-77e86062dfdf653f)



running 3 tests

test test_discovery_async_std_ipv4 ... ok

test test_discovery_async_std_ipv6 ... ok

test test_expired_async_std ... ok



test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.03s



     Running tests/use-tokio.rs (/home/mxinden/code/github.com/libp2p/rust-libp2p/target/debug/deps/use_tokio-278cda36b01406d1)



running 3 tests

test test_expired_tokio ... FAILED

test test_discovery_tokio_ipv4 ... ok

test test_discovery_tokio_ipv6 ... ok



failures:



---- test_expired_tokio stdout ----

thread 'test_expired_tokio' panicked at 'called `Result::unwrap()` on an `Err` value: Elapsed(())', protocols/mdns/tests/use-tokio.rs:55:10

note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace





failures:

    test_expired_tokio



test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 9.15s



error: test failed, to rerun pass '--test use-tokio'

Very rare situation, I guess tokio (explicitly non_blocking) takes longer to find the peers than AsynIO. If so, I increase the expiration time and query request a little

@mxinden
Copy link
Member

mxinden commented Jul 27, 2022

Very rare situation, I guess tokio (explicitly non_blocking) takes longer to find the peers than AsynIO. If so, I increase the expiration time and query request a little

That would be surprising to me, given that the timeout is on the order of seconds, still something worth trying @gallegogt.

@gallegogt
Copy link
Contributor Author

Hi @mxinden and @thomaseizinger can you check if the error persist please ?

@thomaseizinger
Copy link
Contributor

Hi @mxinden and @thomaseizinger can you check if the error persist please ?

Yep, CI is still failing.

@thomaseizinger
Copy link
Contributor

I can't reproduce it locally anymore :/

@gallegogt
Copy link
Contributor Author

@thomaseizinger done with last comments.

@thomaseizinger
Copy link
Contributor

@thomaseizinger done with last comments.

Thanks!

Just one note for future PRs, we tend to not force-push on this repository because PRs will be squash-merged in the end so regular merge commits of e.g. master are completely fine :)

@thomaseizinger
Copy link
Contributor

I've kicked CI again and will merge once it passes!

Given the latest release, this patch now targets `libp2p-mdns` `v0.40.0` and not
`v0.39.0`.
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.

🙏 Thanks @gallegogt and @thomaseizinger!

@tomaka
Copy link
Member

tomaka commented Oct 20, 2022

When use the Tokio library with mdns module, it is polling every time the UDP socket; causing hight CPU usage.

I've just discovered this PR. Did we ever find out what causes this? If not, it seems to me that this PR was done to bypass the issue, not fix it.

@rkuhn
Copy link
Contributor

rkuhn commented Oct 20, 2022

See #2591 for my investigation into this: the short story is that epoll immediately returns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants