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

Clean up Mutex/Instant::now() use for send message error logging #2158

Closed
wants to merge 6 commits into from

Conversation

recatek
Copy link
Contributor

@recatek recatek commented Feb 19, 2025

No description provided.

@Ralith
Copy link
Collaborator

Ralith commented Feb 19, 2025

This adds abstraction to simple code and introduces some complex cfg gates. Can you elaborate on the motivation?

@recatek
Copy link
Contributor Author

recatek commented Feb 19, 2025

Sure. If you don't have/use logging, this saves a little space in UdpSocketState, reduces some code duplication, and skips an Instant::now(). Overall it also makes it easier to audit for usage of Instant::now() in quinn-proto/quinn-udp (trying to stay I/O-agnostic).

Copy link
Collaborator

@gretchenfrage gretchenfrage left a comment

Choose a reason for hiding this comment

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

Sure. If you don't have/use logging, this saves a little space in UdpSocketState, reduces some code duplication, and skips an Instant::now(). Overall it also makes it easier to audit for usage of Instant::now() in quinn-proto/quinn-udp (trying to stay I/O-agnostic).

Storing a Mutex<Instant> per UDP socket and calling Instant::now() both seem trivial in cost. Reducing code duplication at the cost of net-increasing lines of code and adding cfg-gated type aliases seems like a net loss in terms of code simplicity.

I'm in favor of locking down usage of Instant::now(), but perhaps it would be better to start with more clearly articulating what your target use case is specifically and work from there to see how we can accommodate it?

@djc
Copy link
Member

djc commented Feb 19, 2025

If you want to go here (I hope this is motivated by actual benchmarks rather than "premature" optimization efforts), I don't think this is the right way to go. Instead, I'd extract the error code into an ErrorSink type (not a trait, and definitely not a type alias) which could get swapped out with different implementations depending on platform and/or features.

@recatek
Copy link
Contributor Author

recatek commented Feb 19, 2025

Using an ErrorSink is a great idiom, thanks, I switched to that. Overall it's less about perf and more about consistency. Particularly quinn-proto but also, as far as I can tell, quinn-udp both appear to be built to avoid calling Instant::now() in business code to leave that part of syscall/IO work to the user. I did a review of those two crates and saw one use of it in business code (removed in #2157), many usages of it in tests (which is fine), and this use in logging. I figured that reducing the places where it's acceptably called would make it easier to audit these usages. That it spares some bytes and avoids a syscall or two at runtime is a nice but extremely minor value add.

@djc
Copy link
Member

djc commented Feb 19, 2025

Overall it's less about perf and more about consistency. Particularly quinn-proto but also, as far as I can tell, quinn-udp both appear to be built to avoid calling Instant::now() in business code to leave that part of syscall/IO work to the user. I did a review of those two crates and saw one use of it in business code (removed in #2157), many usages of it in tests (which is fine), and this use in logging. I figured that reducing the places where it's acceptably called would make it easier to audit these usages. That it spares some bytes and avoids a syscall or two at runtime is a nice but extremely minor value add.

Well, I think you're overindexing on a particular aspect of a design goal - our design goal for quinn-proto was that it would be deterministic (that is, all function call outputs can be fully determined from function call inputs). That means there should not be Instant::now() calls with legible values. The instance you found did not actually have a legible value. I don't think the use for logging in quinn-udp is particularly legible, and we definitely don't have the deterministicness goals for quinn-udp (since that's all about interacting with the network subsystem).

As is, I don't think we should merge this changes. If you can clean up the commit history (the 2nd or 3rd time I asked...) to have one clean commit that refactors the current implementation to have a better abstraction boundary, and then a second commit that makes the implementation optional, we can consider whether that trade-off makes sense here.

@recatek
Copy link
Contributor Author

recatek commented Feb 19, 2025

If you can clean up the commit history (the 2nd or 3rd time I asked...)

Sorry, I'm used to squashing before merging a PR, not beforehand. I'm not sure what is being asked for here but I can look it up and try my best. The current state of the files changed in the PR should be accurate to what I'd like to merge. Do you want me to close this and open a new clean PR?

current implementation to have a better abstraction boundary, and then a second commit that makes the implementation optional

Is the abstraction boundary you're asking for here the ErrorSink or something else?

FWIW I'm not terribly committed to this so I'm happy to just close this if it isn't a decent change.

@recatek
Copy link
Contributor Author

recatek commented Feb 19, 2025

I think that cleaned it up as requested?

@recatek recatek force-pushed the last-send-error branch 4 times, most recently from f12b4c6 to 575468c Compare February 19, 2025 18:42
recatek and others added 5 commits February 19, 2025 13:44
Clean up Mutex/Instant::now() use for send message error logging

Reverting incorporated change?

Eliminating an Instant::now() in BBR bandwidth estimation code

This was the only case where `Instant::now()` is used in quinn-proto or quinn-udp for anything other than tests or rate-limiting logging. Making this change to keep these two crates more IO-agnostic.
@recatek
Copy link
Contributor Author

recatek commented Feb 19, 2025

I have unbelievably messed up this branch trying to squash it (I have no idea what I'm doing here) and nobody wants this change so I'm just going to close it.

@recatek recatek closed this Feb 19, 2025
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.

5 participants