dnsserver: Rely on dns.Server.ShutdownContext to gracefully stop#7517
Conversation
fa72343 to
0855a2d
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #7517 +/- ##
==========================================
+ Coverage 55.70% 62.62% +6.92%
==========================================
Files 224 274 +50
Lines 10016 18318 +8302
==========================================
+ Hits 5579 11472 +5893
- Misses 3978 6178 +2200
- Partials 459 668 +209 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Conflict caused by #7562 but I think this PR is definitely worth doing still. Please rebase when you have a moment, thanks! |
0855a2d to
58fd2cd
Compare
|
If I read correctly, dns.Server.Shutdown / ShutdownContext already have protections to be safe for concurrent calls: https://github.com/miekg/dns/blob/294d37389cccc53250740798dde72a0c1810be2a/server.go#L398-L448 Need to understand whether |
58fd2cd to
e773f3d
Compare
|
I ran similar tests as in #7314, which has the stacktrace visible. There's also |
|
I struggle how to make |
|
Yeah +1 for removing it now with |
|
How about a test that starts a server, sets a very short |
|
I'm not sure that can reliably work unless there is an active TCP connection. But assuming it does, how does this verify that |
|
Yeah this would be a new test. I would remove the idempotency one with |
|
Which behavior is preferred for |
e773f3d to
6f55dd1
Compare
6f55dd1 to
c9210b3
Compare
|
@thevilledev Is this the test you had in mind? The biggest downside is it uses default value for graceTimeout which is 5 seconds. |
|
Yeah I think that's the right idea. Although I missed the fact that we can't change What do you think of an in-package test instead? I did the following test using your func TestGracefulStopTimeout_Internal(t *testing.T) {
p := new(blocking)
cfg := testConfig("dns", p)
s, err := NewServer("127.0.0.1:0", []*Config{cfg})
if err != nil {
t.Fatalf("NewServer failed: %v", err)
}
// Shorten the graceful timeout
s.graceTimeout = 500 * time.Millisecond
pc, err := net.ListenPacket("udp", "127.0.0.1:0")
if err != nil {
t.Fatalf("ListenPacket failed: %v", err)
}
defer pc.Close()
go s.ServePacket(pc)
udp := pc.LocalAddr().String()
// Block the handler
p.lock.Lock()
defer p.lock.Unlock()
m := new(dns.Msg)
m.SetQuestion("example.com.", dns.TypeA)
// Readiness loop to avoid flakiness
deadline := time.Now().Add(2 * time.Second)
for {
_, err := dns.Exchange(m, udp)
if err == nil || time.Now().After(deadline) {
break
}
time.Sleep(10 * time.Millisecond)
}
err = s.Stop()
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatalf("expected context.DeadlineExceeded, got %v", err)
}
}
IMO returning it only on the first call would hide failures from later callers which kinda complicates err handling. With |
|
IIUC the socket is ready and the only source of flakiness is |
dnsserver.Server.dnsWg does nothing but dns.Server tracks its connections. Signed-off-by: Ilya Kulakov <kulakov.ilya@gmail.com>
c9210b3 to
1c3c9b5
Compare
thevilledev
left a comment
There was a problem hiding this comment.
You're right. Just me being too cautious for Github Actions 😁
LGTM - I'll let others a chance to also review, but lets merge after couple of days if nothing else pops up. Thanks @Kentzo!
1. Why is this pull request needed and what does it do?
dnsserver.Server.Stopdoesn't properly wait for connections:dsnserver.Server.dnsWgis a no-opand
dns.Server.ShutownContextis not used.2. Which issues (if any) are related?
None
3. Which documentation changes (if any) need to be made?
None
4. Does this introduce a backward incompatible change or deprecation?
No