diff --git a/cmd/common-main.go b/cmd/common-main.go index 68edba93c..956ee0fe3 100644 --- a/cmd/common-main.go +++ b/cmd/common-main.go @@ -51,7 +51,7 @@ func init() { logger.RegisterError(config.FmtError) rand.Seed(time.Now().UTC().UnixNano()) - globalDNSCache = xhttp.NewDNSCache(3*time.Second, 10*time.Second) + globalDNSCache = xhttp.NewDNSCache(10*time.Second, 3*time.Second) initGlobalContext() diff --git a/cmd/http/dial_dnscache.go b/cmd/http/dial_dnscache.go index 8c139f9a1..91785e35b 100644 --- a/cmd/http/dial_dnscache.go +++ b/cmd/http/dial_dnscache.go @@ -97,8 +97,9 @@ type DNSCache struct { lookupHostFn func(ctx context.Context, host string) ([]string, error) lookupTimeout time.Duration - cache map[string][]string - closer func() + cache map[string][]string + doneOnce sync.Once + doneCh chan struct{} } // NewDNSCache initializes DNS cache resolver and starts auto refreshing @@ -113,26 +114,24 @@ func NewDNSCache(freq time.Duration, lookupTimeout time.Duration) *DNSCache { lookupTimeout = defaultLookupTimeout } - ticker := time.NewTicker(freq) - ch := make(chan struct{}) - closer := func() { - ticker.Stop() - close(ch) - } - r := &DNSCache{ lookupHostFn: net.DefaultResolver.LookupHost, lookupTimeout: lookupTimeout, cache: make(map[string][]string, cacheSize), - closer: closer, + doneCh: make(chan struct{}), } + timer := time.NewTimer(freq) go func() { + defer timer.Stop() + for { select { - case <-ticker.C: + case <-timer.C: + timer.Reset(freq) + r.Refresh() - case <-ch: + case <-r.doneCh: return } } @@ -188,10 +187,7 @@ func (r *DNSCache) Refresh() { // Stop stops auto refreshing. func (r *DNSCache) Stop() { - r.Lock() - defer r.Unlock() - if r.closer != nil { - r.closer() - r.closer = nil - } + r.doneOnce.Do(func() { + close(r.doneCh) + }) }