From 9701998f8220b7854489c27ccc60904358a57d28 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Wed, 25 Mar 2015 16:55:40 +0100 Subject: [PATCH] Add negative cache time to global discovery This reduces the amount of external queries by not repeating a query for a given address if we have failed within the last three minutes. --- internal/discover/discover.go | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/internal/discover/discover.go b/internal/discover/discover.go index 0485446a..54baa382 100644 --- a/internal/discover/discover.go +++ b/internal/discover/discover.go @@ -27,14 +27,17 @@ type Discoverer struct { localBcastIntv time.Duration localBcastStart time.Time cacheLifetime time.Duration + negCacheCutoff time.Duration broadcastBeacon beacon.Interface multicastBeacon beacon.Interface - registry map[protocol.DeviceID][]CacheEntry - registryLock sync.RWMutex extPort uint16 localBcastTick <-chan time.Time forcedBcastTick chan time.Time + registryLock sync.RWMutex + registry map[protocol.DeviceID][]CacheEntry + lastLookup map[protocol.DeviceID]time.Time + clients []Client mut sync.RWMutex } @@ -54,7 +57,9 @@ func NewDiscoverer(id protocol.DeviceID, addresses []string) *Discoverer { listenAddrs: addresses, localBcastIntv: 30 * time.Second, cacheLifetime: 5 * time.Minute, + negCacheCutoff: 3 * time.Minute, registry: make(map[protocol.DeviceID][]CacheEntry), + lastLookup: make(map[protocol.DeviceID]time.Time), } } @@ -155,18 +160,28 @@ func (d *Discoverer) ExtAnnounceOK() map[string]bool { func (d *Discoverer) Lookup(device protocol.DeviceID) []string { d.registryLock.RLock() cached := d.filterCached(d.registry[device]) + lastLookup := d.lastLookup[device] d.registryLock.RUnlock() d.mut.RLock() defer d.mut.RUnlock() - var addrs []string if len(cached) > 0 { - addrs = make([]string, len(cached)) + // There are cached address entries. + addrs := make([]string, len(cached)) for i := range cached { addrs[i] = cached[i].Address } - } else if len(d.clients) != 0 && time.Since(d.localBcastStart) > d.localBcastIntv { + return addrs + } + + if time.Since(lastLookup) < d.negCacheCutoff { + // We have recently tried to lookup this address and failed. Lets + // chill for a while. + return nil + } + + if len(d.clients) != 0 && time.Since(d.localBcastStart) > d.localBcastIntv { // Only perform external lookups if we have at least one external // server client and one local announcement interval has passed. This is // to avoid finding local peers on their remote address at startup. @@ -187,6 +202,7 @@ func (d *Discoverer) Lookup(device protocol.DeviceID) []string { seen := make(map[string]struct{}) now := time.Now() + var addrs []string for result := range results { for _, addr := range result { _, ok := seen[addr] @@ -203,9 +219,13 @@ func (d *Discoverer) Lookup(device protocol.DeviceID) []string { d.registryLock.Lock() d.registry[device] = cached + d.lastLookup[device] = time.Now() d.registryLock.Unlock() + + return addrs } - return addrs + + return nil } func (d *Discoverer) Hint(device string, addrs []string) {