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

perf/refactor: use tokio_util::sync::PollSender for ActiveSession -> SessionManager messages #4603

Merged
merged 12 commits into from
Sep 22, 2023

Conversation

cbrit
Copy link
Contributor

@cbrit cbrit commented Sep 14, 2023

Meant to address #2695. There is already unit test coverage for the branches I touched; please let me know if there are any other unit tests that would be appropriate I didn't notice.

Note: I'm not the assignee for the issue, but it's been stale long enough that I went ahead.

@cbrit
Copy link
Contributor Author

cbrit commented Sep 14, 2023

I'm realizing now I maybe should have opened the PR directly on the repo instead of through my fork, because it didn't present me with the template flow. Sorry! Let me know if I should re-open.

@cbrit cbrit changed the title refactor: use tokio_util::sync::PollSender for ActiveSession -> SessionManager messages perf/refactor: use tokio_util::sync::PollSender for ActiveSession -> SessionManager messages Sep 14, 2023
@onbjerg onbjerg added C-debt Refactor of code section that is hard to understand or maintain C-perf A change motivated by improving speed, memory usage or disk footprint A-devp2p Related to the Ethereum P2P protocol A-networking Related to networking in general labels Sep 18, 2023
Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

cool! this looks good.

only smol nits,

sorry for the delay

Comment on lines 585 to 588
Poll::Ready(Ok(_)) => {
let _ = to_session_manager_poll_tx.send_item(msg);
}
}
Poll::Ready(Err(_)) => {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

the error cases mean that the channel is closed, which should not be possible but we should return Poll::Ready in that case

Copy link
Contributor Author

@cbrit cbrit Sep 19, 2023

Choose a reason for hiding this comment

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

Was this a bug in the previous logic? I was trying to replicate it:

TrySendError::Closed(_) => {}

Maybe I'm misreading. Happy to fix just want to clarify!

Comment on lines 644 to 647
if let Poll::Ready(Ok(_)) = to_session_manager_poll_tx.poll_reserve(cx) {
let _ = to_session_manager_poll_tx.send_item(
ActiveSessionMessage::ProtocolBreach { peer_id: this.remote_peer_id },
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This does not quite have the same effect as before,

here I think we can just set the message to pending_message_to_session, which will make sure the message gets delivered

@cbrit
Copy link
Contributor Author

cbrit commented Sep 20, 2023

cool! this looks good.

only smol nits,

sorry for the delay

Fixed!

Comment on lines 488 to 490
let smtx = this.to_session_manager.inner().to_owned();
let mut to_session_manager_poll_tx = PollSender::new(smtx);

Copy link
Collaborator

Choose a reason for hiding this comment

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

this is an issue because this PollSender is dropped when poll returns, meaning if it's in the process of acquiring a permit it's progress gets lost,

hmm now this suddenly needs a bit more work, because to_session_manager is a MeteredSender, but PollSender requires mpsc::Sender...

so if we want to keep the metrics of MeteredSender we probably need a new helper type MeteredPollSender that mimics PollSender

does that make sense?

Copy link
Contributor Author

@cbrit cbrit Sep 20, 2023

Choose a reason for hiding this comment

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

Ah yes it does. Actually originally I changed MeteredSender to wrap a PollSender but opted not to because of complexity and it felt out of scope. A separate type makes more sense! I forgot to consider the ownership aspect (too much Go dev lately.. :) ).

I'll get on that.

EDIT: One question: MeteredSender counts errors, but the only error condition here is a closed connection, which can only happen once. Should I just forego the error count on the new type, or instead replace it with a count of back pressure on the channel or something?

Copy link
Contributor Author

@cbrit cbrit Sep 21, 2023

Choose a reason for hiding this comment

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

Updated with some assumptions about the above.

Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

nice, this should work, love the additional metric

last style nits

Comment on lines 337 to 343
let sender = self.to_session_manager.inner().get_ref();
if sender.is_none() {
return Ok(())
}

match sender
.unwrap()
Copy link
Collaborator

Choose a reason for hiding this comment

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

style:

let's use let Some(sender) ... {else return Ok(())}
pattern here

Copy link
Contributor Author

@cbrit cbrit Sep 22, 2023

Choose a reason for hiding this comment

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

I am embarrassed to say I have not seen let-else before. This is wonderful.

Copy link
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

awesome, this is great, tysm.

no more wake by ref hack

@codecov
Copy link

codecov bot commented Sep 22, 2023

Codecov Report

Merging #4603 (25eca1a) into main (e83d3aa) will decrease coverage by 0.05%.
Report is 6 commits behind head on main.
The diff coverage is 87.23%.

Impacted file tree graph

Files Changed Coverage Δ
crates/net/network/src/session/active.rs 84.48% <85.71%> (-0.65%) ⬇️
crates/metrics/src/common/mpsc.rs 25.87% <87.50%> (-1.86%) ⬇️
crates/net/network/src/session/mod.rs 69.82% <100.00%> (-1.30%) ⬇️

... and 9 files with indirect coverage changes

Flag Coverage Δ
integration-tests 16.53% <36.17%> (-0.03%) ⬇️
unit-tests 63.55% <82.97%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
reth binary 32.11% <87.50%> (-0.07%) ⬇️
blockchain tree 83.73% <ø> (ø)
pipeline 88.53% <ø> (ø)
storage (db) 73.70% <ø> (ø)
trie 94.73% <ø> (-0.04%) ⬇️
txpool 49.82% <ø> (ø)
networking 77.07% <86.95%> (-0.13%) ⬇️
rpc 57.87% <ø> (ø)
consensus 63.09% <ø> (ø)
revm 28.33% <ø> (ø)
payload builder 8.32% <ø> (ø)
primitives 86.54% <ø> (ø)

@mattsse mattsse added this pull request to the merge queue Sep 22, 2023
Merged via the queue into paradigmxyz:main with commit 675c6bf Sep 22, 2023
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-devp2p Related to the Ethereum P2P protocol A-networking Related to networking in general C-debt Refactor of code section that is hard to understand or maintain C-perf A change motivated by improving speed, memory usage or disk footprint
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants