ResolveAddrsParallel resolves multiple addresses concurrently and caches results. This should be called before rendering to pre-warm the cache.
(addrs []string)
| 233 | // ResolveAddrsParallel resolves multiple addresses concurrently and caches results. |
| 234 | // This should be called before rendering to pre-warm the cache. |
| 235 | func (r *Resolver) ResolveAddrsParallel(addrs []string) { |
| 236 | // dedupe and filter addresses that need resolution |
| 237 | unique := make(map[string]struct{}) |
| 238 | for _, addr := range addrs { |
| 239 | if addr == "" || addr == "*" { |
| 240 | continue |
| 241 | } |
| 242 | // skip if already cached |
| 243 | r.mutex.RLock() |
| 244 | _, exists := r.cache[addr] |
| 245 | r.mutex.RUnlock() |
| 246 | if exists { |
| 247 | continue |
| 248 | } |
| 249 | unique[addr] = struct{}{} |
| 250 | } |
| 251 | |
| 252 | if len(unique) == 0 { |
| 253 | return |
| 254 | } |
| 255 | |
| 256 | var wg sync.WaitGroup |
| 257 | // limit concurrency to avoid overwhelming dns |
| 258 | sem := make(chan struct{}, 32) |
| 259 | |
| 260 | for addr := range unique { |
| 261 | wg.Add(1) |
| 262 | go func(a string) { |
| 263 | defer wg.Done() |
| 264 | sem <- struct{}{} |
| 265 | defer func() { <-sem }() |
| 266 | r.ResolveAddr(a) |
| 267 | }(addr) |
| 268 | } |
| 269 | |
| 270 | wg.Wait() |
| 271 | } |
| 272 | |
| 273 | // ResolveAddrsParallel is a convenience function using the global resolver |
| 274 | func ResolveAddrsParallel(addrs []string) { |