mirror of
https://github.com/coredns/coredns.git
synced 2026-10-16 23:35:43 -04:00
plugin/cache: Fix timed stale caused refreshes (#8587)
This commit is contained in:
6
plugin/cache/handler.go
vendored
6
plugin/cache/handler.go
vendored
@@ -54,7 +54,7 @@ func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
|
|||||||
if c.verifyStale {
|
if c.verifyStale {
|
||||||
failureRecheck := c.staleRecheck
|
failureRecheck := c.staleRecheck
|
||||||
nowFunc := c.now
|
nowFunc := c.now
|
||||||
trackRefresh := failureRecheck > 0
|
trackRefresh := failureRecheck > 0 || c.verifyStaleTimeout > 0
|
||||||
if !trackRefresh || i.beginRefresh(now, failureRecheck) {
|
if !trackRefresh || i.beginRefresh(now, failureRecheck) {
|
||||||
refreshState := authenticatedRefreshState(state)
|
refreshState := authenticatedRefreshState(state)
|
||||||
crr := &ResponseWriter{ResponseWriter: w, Cache: c, state: refreshState, server: server, do: do, ad: ad, cd: cd}
|
crr := &ResponseWriter{ResponseWriter: w, Cache: c, state: refreshState, server: server, do: do, ad: ad, cd: cd}
|
||||||
@@ -187,9 +187,7 @@ func (c *Cache) verifyWithTimeout(ctx context.Context, state request.Request, w
|
|||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
rc, re := c.doRefresh(refreshCtx, state, cw)
|
rc, re := c.doRefresh(refreshCtx, state, cw)
|
||||||
if failureRecheck > 0 {
|
i.endRefresh(now(), failureRecheck, cw.refreshed)
|
||||||
i.endRefresh(now(), failureRecheck, cw.refreshed)
|
|
||||||
}
|
|
||||||
done <- result{rc, re}
|
done <- result{rc, re}
|
||||||
}()
|
}()
|
||||||
timer := time.NewTimer(c.verifyStaleTimeout)
|
timer := time.NewTimer(c.verifyStaleTimeout)
|
||||||
|
|||||||
43
plugin/cache/serve_stale_recheck_test.go
vendored
43
plugin/cache/serve_stale_recheck_test.go
vendored
@@ -299,6 +299,49 @@ func TestServeStaleFailureRecheckVerifyTimeoutCoalesces(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServeStaleVerifyTimeoutCoalescesWithoutFailureRecheck(t *testing.T) {
|
||||||
|
clock := newStaleRecheckClock()
|
||||||
|
c := New()
|
||||||
|
c.now = clock.Now
|
||||||
|
c.minpttl = 0
|
||||||
|
c.minnttl = 0
|
||||||
|
c.staleUpTo = time.Hour
|
||||||
|
c.verifyStale = true
|
||||||
|
c.verifyStaleTimeout = 10 * time.Millisecond
|
||||||
|
c.Next = ttlBackend(1)
|
||||||
|
|
||||||
|
req := new(dns.Msg)
|
||||||
|
req.SetQuestion("cached.org.", dns.TypeA)
|
||||||
|
serveStaleRecheckRequest(t, c, req)
|
||||||
|
item := c.exists("cached.org.", dns.TypeA, dns.ClassINET, false, false)
|
||||||
|
clock.Set(2 * time.Second)
|
||||||
|
|
||||||
|
var calls atomic.Int32
|
||||||
|
started := make(chan struct{}, 2)
|
||||||
|
completed := make(chan struct{}, 2)
|
||||||
|
release := make(chan struct{})
|
||||||
|
defer close(release)
|
||||||
|
failure := servFailBackend(30)
|
||||||
|
c.Next = plugin.HandlerFunc(func(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||||||
|
calls.Add(1)
|
||||||
|
started <- struct{}{}
|
||||||
|
<-release
|
||||||
|
rcode, err := failure.ServeDNS(ctx, w, r)
|
||||||
|
completed <- struct{}{}
|
||||||
|
return rcode, err
|
||||||
|
})
|
||||||
|
|
||||||
|
serveStaleRecheckRequest(t, c, req)
|
||||||
|
waitForStaleSignal(t, started, "background verify did not start")
|
||||||
|
serveStaleRecheckRequest(t, c, req)
|
||||||
|
if got := calls.Load(); got != 1 {
|
||||||
|
t.Fatalf("expected concurrent stale request to share the in-flight verify, got %d attempts", got)
|
||||||
|
}
|
||||||
|
|
||||||
|
release <- struct{}{}
|
||||||
|
waitForStaleRefresh(t, completed, item)
|
||||||
|
}
|
||||||
|
|
||||||
func TestServeStaleFailureRecheckDisabledPreservesVerifyBehavior(t *testing.T) {
|
func TestServeStaleFailureRecheckDisabledPreservesVerifyBehavior(t *testing.T) {
|
||||||
clock := newStaleRecheckClock()
|
clock := newStaleRecheckClock()
|
||||||
c := New()
|
c := New()
|
||||||
|
|||||||
Reference in New Issue
Block a user