Lookup attempts to resolve the device ID using any of the added Finders, while obeying the cache settings.
(ctx context.Context, deviceID protocol.DeviceID)
| 111 | // Lookup attempts to resolve the device ID using any of the added Finders, |
| 112 | // while obeying the cache settings. |
| 113 | func (m *manager) Lookup(ctx context.Context, deviceID protocol.DeviceID) (addresses []string, err error) { |
| 114 | m.mut.RLock() |
| 115 | for _, finder := range m.finders { |
| 116 | if cacheEntry, ok := finder.cache.Get(deviceID); ok { |
| 117 | // We have a cache entry. Lets see what it says. |
| 118 | |
| 119 | if cacheEntry.found && time.Since(cacheEntry.when) < finder.cacheTime { |
| 120 | // It's a positive, valid entry. Use it. |
| 121 | slog.DebugContext(ctx, "Found cached discovery entry", "device", deviceID, "finder", finder, "entry", cacheEntry) |
| 122 | addresses = append(addresses, cacheEntry.Addresses...) |
| 123 | continue |
| 124 | } |
| 125 | |
| 126 | valid := time.Now().Before(cacheEntry.validUntil) || time.Since(cacheEntry.when) < finder.negCacheTime |
| 127 | if !cacheEntry.found && valid { |
| 128 | // It's a negative, valid entry. We should not make another |
| 129 | // attempt right now. |
| 130 | slog.DebugContext(ctx, "Negative cache entry", "device", deviceID, "finder", finder, "until1", cacheEntry.when.Add(finder.negCacheTime), "until2", cacheEntry.validUntil) |
| 131 | continue |
| 132 | } |
| 133 | |
| 134 | // It's expired. Ignore and continue. |
| 135 | } |
| 136 | |
| 137 | // Perform the actual lookup and cache the result. |
| 138 | if addrs, err := finder.Lookup(ctx, deviceID); err == nil { |
| 139 | slog.DebugContext(ctx, "Got finder result", "device", deviceID, "finder", finder, "address", addrs) |
| 140 | addresses = append(addresses, addrs...) |
| 141 | finder.cache.Set(deviceID, CacheEntry{ |
| 142 | Addresses: addrs, |
| 143 | when: time.Now(), |
| 144 | found: len(addrs) > 0, |
| 145 | }) |
| 146 | } else { |
| 147 | // Lookup returned error, add a negative cache entry. |
| 148 | entry := CacheEntry{ |
| 149 | when: time.Now(), |
| 150 | found: false, |
| 151 | } |
| 152 | if err, ok := err.(cachedError); ok { |
| 153 | entry.validUntil = time.Now().Add(err.CacheFor()) |
| 154 | } |
| 155 | finder.cache.Set(deviceID, entry) |
| 156 | } |
| 157 | } |
| 158 | m.mut.RUnlock() |
| 159 | |
| 160 | addresses = stringutil.UniqueTrimmedStrings(addresses) |
| 161 | slices.Sort(addresses) |
| 162 | |
| 163 | slog.DebugContext(ctx, "Final lookup results", "device", deviceID, "addresses", addresses) |
| 164 | |
| 165 | return addresses, nil |
| 166 | } |
| 167 | |
| 168 | func (*manager) String() string { |
| 169 | return "discovery cache" |