github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/file/s3file/s3transport/dns.go (about)

     1  package s3transport
     2  
     3  import (
     4  	"net"
     5  	"sync"
     6  	"time"
     7  )
     8  
     9  const dnsCacheTime = 5 * time.Second
    10  
    11  type resolverCacheEntry struct {
    12  	result     []net.IP
    13  	resolvedAt time.Time
    14  }
    15  
    16  type resolver struct {
    17  	lookupIP func(host string) ([]net.IP, error)
    18  	now      func() time.Time
    19  	cacheMu  sync.Mutex
    20  	cache    map[string]resolverCacheEntry
    21  }
    22  
    23  func newResolver(lookupIP func(host string) ([]net.IP, error), now func() time.Time) *resolver {
    24  	return &resolver{
    25  		lookupIP: lookupIP,
    26  		now:      now,
    27  		cache:    map[string]resolverCacheEntry{},
    28  	}
    29  }
    30  
    31  var defaultResolver = newResolver(net.LookupIP, time.Now)
    32  
    33  func (r *resolver) LookupIP(host string) ([]net.IP, error) {
    34  	r.cacheMu.Lock()
    35  	entry, ok := r.cache[host]
    36  	r.cacheMu.Unlock()
    37  	now := r.now()
    38  	if ok && now.Sub(entry.resolvedAt) < dnsCacheTime {
    39  		return entry.result, nil
    40  	}
    41  	ips, err := r.lookupIP(host)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	r.cacheMu.Lock()
    46  	r.cache[host] = resolverCacheEntry{ips, now}
    47  	r.cacheMu.Unlock()
    48  	return ips, nil
    49  }