-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Goroutine Pool for UDP datagram reads #1416
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d like to see this with errgroup as I think that’s going to be better here.
Thanks for the quick review! I changed the waitgroup/error channel out for an error group. |
@tmthrgd is this good to merge? |
@miekg I'm not a huge fan. Pools and multiple readers are hard to get right in a general sense. What might improve things for one workload, could easily worsen things in others. In particular I know things can get very counterintuitive with high core count CPUs. |
"strings" | ||
"sync" | ||
|
||
"golang.org/x/sync/errgroup" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't formatted properly. Stdlib should be grouped up separately from other imports.
) | ||
|
||
if isUDP { | ||
m, sUDP, err = reader.ReadUDP(lUDP, rtimeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's nothing to actually ensure this call unblocks when the errgroup returns with an error. This could easily end up still reading in one go routine while others have already exited.
if cap(m) == srv.UDPSize { | ||
srv.udpPool.Put(m[:srv.UDPSize]) | ||
|
||
g := new(errgroup.Group) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var g errgroup.Group
|
||
g := new(errgroup.Group) | ||
|
||
for i := 0; i < runtime.NumCPU(); i++ { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if NumCPU is correct here or not.
Maybe we could define some sort of interface for people who want to implement pools of some kind. I'm not sure. |
Ack. Thanks for your thoughts.
Tend to agree, so I'll close this PR. As for an interface, nothing forces
you to use all the things in this library, so prolly best to not define
anything for this use case
…On Sat, 29 Apr 2023, 06:46 Tom Thorogood, ***@***.***> wrote:
Maybe we could define some sort of interface for people who want to
implement pools of some kind. I'm not sure.
—
Reply to this email directly, view it on GitHub
<#1416 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACWIW6KYTAZCOW4CI6UK5LXDSMK3ANCNFSM6AAAAAAURK3OQ4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
This PR puts UDP server datagram reads into a Goroutine pool, and was made to address this issue within CoreDNS: coredns/coredns#5595 (comment)
Here are some benchmarks of CoreDNS with and without my changes, with one server, using DNSperf.
Without my change:
With my change:
So notably we see CPU utilization went up significantly but QPS went up ~50%, and avg latency is down.
This is a pretty stupid change, but it seems pretty impactful. Let me know if there's anything you'd like to see here; from my interpretation, all affected method calls should be thread-safe (but let me know if I've missed anything!).