mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-18 12:39:54 +00:00
[client] Scope mgmt cache initial resolve to server lifetime
Background initial resolves used context.Background(), so they outlived a server Stop() and kept running (up to dnsTimeout) against a cache that was already being discarded. Thread the server-lifetime ctx from UpdateFromServerDomains through kickoffResolve into AddDomain so Stop() cancels in-flight resolves. The ctx is not per-sync, so a fast-returning sync still won't cancel them.
This commit is contained in:
@@ -520,9 +520,10 @@ func (m *Resolver) GetCachedDomains() domain.List {
|
||||
// Empty updates are ignored to prevent clearing infrastructure domains during partial updates.
|
||||
// UpdateFromServerDomains records the requested domains and kicks off their
|
||||
// resolution in the background, returning without blocking on DNS so it stays
|
||||
// off the engine sync lock held by the caller. ctx is unused: background
|
||||
// resolves use context.Background() so a fast-returning sync can't cancel them.
|
||||
func (m *Resolver) UpdateFromServerDomains(_ context.Context, serverDomains dnsconfig.ServerDomains) (domain.List, error) {
|
||||
// off the engine sync lock held by the caller. ctx scopes the background
|
||||
// resolves to the server lifetime: it is not per-sync, so a fast-returning
|
||||
// sync won't cancel them, but a server Stop will.
|
||||
func (m *Resolver) UpdateFromServerDomains(ctx context.Context, serverDomains dnsconfig.ServerDomains) (domain.List, error) {
|
||||
newDomains := m.extractDomainsFromServerDomains(serverDomains)
|
||||
var removedDomains domain.List
|
||||
|
||||
@@ -540,14 +541,14 @@ func (m *Resolver) UpdateFromServerDomains(_ context.Context, serverDomains dnsc
|
||||
removedDomains = m.removeStaleDomains(currentDomains, allDomains)
|
||||
}
|
||||
|
||||
m.kickoffResolve(newDomains)
|
||||
m.kickoffResolve(ctx, newDomains)
|
||||
|
||||
return removedDomains, nil
|
||||
}
|
||||
|
||||
// kickoffResolve marks each domain pending and starts a background resolve,
|
||||
// skipping ones already fresh or in flight. Returns immediately.
|
||||
func (m *Resolver) kickoffResolve(domains domain.List) {
|
||||
func (m *Resolver) kickoffResolve(ctx context.Context, domains domain.List) {
|
||||
for _, d := range domains {
|
||||
dnsName := strings.ToLower(dns.Fqdn(d.PunycodeString()))
|
||||
|
||||
@@ -563,17 +564,18 @@ func (m *Resolver) kickoffResolve(domains domain.List) {
|
||||
continue
|
||||
}
|
||||
|
||||
m.scheduleInitialResolve(d, dnsName)
|
||||
m.scheduleInitialResolve(ctx, d, dnsName)
|
||||
}
|
||||
}
|
||||
|
||||
// scheduleInitialResolve runs AddDomain in the background, deduped per domain
|
||||
// by resolveGroup, clearing the pending marker when it finishes.
|
||||
func (m *Resolver) scheduleInitialResolve(d domain.Domain, dnsName string) {
|
||||
// by resolveGroup, clearing the pending marker when it finishes. ctx is the
|
||||
// server-lifetime context so a Stop cancels in-flight resolves.
|
||||
func (m *Resolver) scheduleInitialResolve(ctx context.Context, d domain.Domain, dnsName string) {
|
||||
key := "initial|" + dnsName
|
||||
_ = m.resolveGroup.DoChan(key, func() (any, error) {
|
||||
defer m.clearPending(dnsName)
|
||||
if err := m.AddDomain(context.Background(), d); err != nil {
|
||||
if err := m.AddDomain(ctx, d); err != nil {
|
||||
log.Warnf("failed to add/update domain=%s: %v", d.SafeString(), err)
|
||||
return struct{}{}, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user