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

Do not pre-allocate memory on streams #1682

Closed
wants to merge 9 commits into from

Conversation

jeromegn
Copy link
Contributor

This PR wraps Recv and Send streams in Option<Box<T>> to prevent significant memory pre-allocation.

Still a few things to verify / do:

  • Make sure there's never a None value when it should be Some
  • Validate the logic here, not sure when to insert a None or a Some exactly...

(Hopefully) Fixes #1677

@jeromegn
Copy link
Contributor Author

I have tested this in corrosion and it significantly reduced memory usage. As far as I can tell everything is working as intended but I'd like somebody to thoroughly review it.

Copy link
Collaborator

@Ralith Ralith 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 like a nice improvement to memory use!

The rule of thumb should be that a stream becomes allocated (i.e. Some) as soon as any frames for it are received, or the user manipulates it. This follows from the need to have somewhere to store the information carried in those frames/manipulations.

quinn-proto/src/connection/streams/mod.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/mod.rs Show resolved Hide resolved
quinn-proto/src/connection/streams/mod.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/mod.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/mod.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/mod.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/recv.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/state.rs Show resolved Hide resolved
quinn-proto/src/connection/streams/state.rs Outdated Show resolved Hide resolved
quinn-proto/src/connection/streams/state.rs Outdated Show resolved Hide resolved
@jeromegn jeromegn requested a review from Ralith October 12, 2023 19:12
@jeromegn jeromegn requested a review from Ralith October 12, 2023 19:54
Copy link
Collaborator

@Ralith Ralith left a comment

Choose a reason for hiding this comment

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

Thanks!

// the line. Best to short-circuit.
let stream = entry.get_mut().as_mut().unwrap();
let stream = match entry.get_mut().as_mut() {
Some(s) => s,
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: this would be a great case or let-else.

Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

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

Nice!

@@ -797,24 +832,26 @@ impl StreamsState {
expanded
}

pub(super) fn max_send_data(&self, id: &StreamId) -> VarInt {
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to squash all the commits and then extract this as a separate prefix commit.

let stream = self
.state
.send
.get_mut(&self.id)
.map(|s| s.get_or_insert_with(|| Box::new(Send::new(max_send_data))))
Copy link
Member

Choose a reason for hiding this comment

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

I feel like there are a few recurring patterns here that would make good candidates for moving into a method somewhere to raise the level of abstraction. We could address that after merging this, but would be great if you can take a whack at it.

@@ -216,7 +216,7 @@ impl<'a> SendStream<'a> {
.state
.send
.get_mut(&self.id)
.map(|s| s.get_or_insert_with(|| Box::new(Send::new(max_send_data))))
.map(get_or_insert_send(max_send_data))
Copy link
Member

Choose a reason for hiding this comment

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

Was actually hoping for something that can also abstract over the self.state.send.get_mut() of it all.

@jeromegn
Copy link
Contributor Author

Shall we merge or are we waiting for a commit history cleanup from me? :)

@djc
Copy link
Member

djc commented Oct 14, 2023

I have a cleaned up branch but was failing to push it up to your remote... let me just push it here.

@djc
Copy link
Member

djc commented Oct 14, 2023

See #1685. Might do more golfing later. @jeromegn would you mind forward porting?

@jeromegn
Copy link
Contributor Author

Made a PR for the forward port: #1686

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.

3 participants