Skip to content

WIP: PEX - Peer Exchange#210

Closed
izderadicka wants to merge 4 commits intoikatson:mainfrom
izderadicka:pex
Closed

WIP: PEX - Peer Exchange#210
izderadicka wants to merge 4 commits intoikatson:mainfrom
izderadicka:pex

Conversation

@izderadicka
Copy link
Contributor

This is WORK IN PROGRESS (WIP) on adding PEX.

I wanted to share early - to get some feedback if I'm moving in wrong direction.

If this "early draft PR" does not work with project workflow, sorry for that, just close it.
WIP PRs did work for me to have place to discuss and share on particular feature, but if this does not fit this project sorry again.

I thought that PEX could be usefull, and should not be so difficult at least on receiving side. And I can try something bit more substantial .... But I do not have much time left - so it can take quite some time to finish.

@ikatson
Copy link
Owner

ikatson commented Aug 24, 2024

On a quick look from phone, seems like a reasonable thing to have. Code is mostly ok, minor comments so far not worth writing them down until this is finished.

Thanks for the early feedback ask, so far so good

where
B: AsRef<[u8]>,
{
pub fn added_peers<'a>(&'a self) -> anyhow::Result<Box<dyn Iterator<Item = PexPeerInfo> + 'a>> {
Copy link
Owner

Choose a reason for hiding this comment

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

I'd avoid allocation here as it's quite easy to do.

two options:

  1. either use itertools::Either (minimal changes to your existing code, good enough)
  2. Option is also an iterator, and you can flatten it.

Option 2 would be smth like this:

if self.added.as_ref().map(|added| added.len() % 6 != 0).unwrap_or(false) {
    bail!(...)
}

let ips = self.added.as_ref().map(|addrs| addrs.chunk_exact(6)).flatten();
let flags = self.added_f.as_ref().map(|flags| flags.iter().copied()).flatten();

return ips.zip(flags).filter_map(|(ip, flags)| PexPeerInfo::from_bytes(ip, flags).ok())

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added flags - added_f - are optional - so we can have addresses but not flags, in that case zip will not work. But chunks might make things easier - will look into it.

Copy link
Owner

Choose a reason for hiding this comment

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

Look into the PR I put into your repo I've done it already

{
// TODO: this is just first attempt at pex - will need more sophistication on adding peers - BEP 40, check number of live, seen peers ...
if let Ok(peers) = msg.added_peers() {
peers.for_each(|peer| {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Clearly adding eagerly is not good - it takes huge amount of CPU - will need to find something better

Copy link
Owner

Choose a reason for hiding this comment

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

What eats CPU exactly out of this?

Copy link
Owner

Choose a reason for hiding this comment

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

Adding eagerly should be the way to go, just need to fix our workaround the issues

@ikatson
Copy link
Owner

ikatson commented Aug 25, 2024

I tried to look into it, and it seems totally ok to me. The peers get added, I don't see why this in particular would increase CPU usage.
Tweaked it all to fix all the things I mentioned + nicer debug

izderadicka#1

/target
.DS_Store No newline at end of file
.DS_Store
/.vscode No newline at end of file
Copy link
Owner

Choose a reason for hiding this comment

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

Please don't remove this. It's for consistent linter / prettifier for JS mostly

@ikatson
Copy link
Owner

ikatson commented Aug 25, 2024

Also profiled in release mode, no CPU issues noticed, works like a charm. On my box, the absolute majority of the CPU is taken by:

  • syscal write to disk (45%)
  • read from network (14%)
  • checksum (9%)
  • write to network (4%)

The rest is rqbit itself + tokio overhead.

@izderadicka
Copy link
Contributor Author

izderadicka commented Aug 25, 2024

Still see about 150% CPU - it's on big swarm - https://releases.ubuntu.com/24.04/ubuntu-24.04-desktop-amd64.iso.torrent?_gl=1*1bi12tz*_gcl_au*MTA4NjA0NjI5Ny4xNzI0NDkzMjYy&_ga=2.207753554.1199975540.1724493262-752598451.1714415561

Only when torrent is downloading, when stopped, CPU is minimal. Looks like this behaviour is only on this pex branch.

@ikatson
Copy link
Owner

ikatson commented Aug 25, 2024

Just checking, can that be that with that branch there's many more live peers that you observe?

The CPU would be proportional to the number of live (i.e. connected and communicating) peers usually.

Otherwise maybe you can profile with perf or whatever you have on your system to see where's the new hotspot? I didn't see any on the torrent I checked

@ikatson
Copy link
Owner

ikatson commented Aug 25, 2024

I'll check that Ubuntu one too

@ikatson
Copy link
Owner

ikatson commented Aug 25, 2024

Just tried the ubuntu one.

System: macbook air m1
Max CPU usage - 80%
Seen peers - about 3000.
Downloading at about 85 megabytes per second.

There are 0 hotspots in the new code, all of "on_received_message" is in "on_received_piece".
Screenshot 2024-08-25 at 21 58 43

  1. Can you ensure you're profiling a release build
  2. Ensure you don't write logs / tracing is at "info" level.

You can use the newly added "make devserver-profile" command to do all that.

@ikatson
Copy link
Owner

ikatson commented Aug 27, 2024

@izderadicka any updates on this? I think I can just go ahead and merge this + izderadicka#1, as it seems useful on its own already for discovering peers even if we don't send our peers yet

@izderadicka
Copy link
Contributor Author

Sorry I did not have time to look at - as I said I do have only limited time - I'm still concerned about increase on CPU.
As I tested on Ubuntu torrent (only rather subjective tests, with top running) - this PR - high CPU, main branch - almost no CPU. Will like to look at it little bit more. Also it now looks only for IPv4 added peers - should look also at other categories.

@ikatson
Copy link
Owner

ikatson commented Aug 28, 2024

Also it now looks only for IPv4 added peers - should look also at other categories.

I addresed this already.

Let's do this: I merge this as-is plus my changes on top. If we figure out perf issues we fix them, but I don't see any so far as I mentioned. The PR is useful already on its own and it doesn't need to wait until all PEX features are implemented.

I'll merge this one instead #221 which includes your changes

@ikatson ikatson closed this Aug 28, 2024
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.

2 participants