Files
gluetun/internal/publicip/multi.go
Quentin McGaw 83b4a3fe55 chore(publicip): refactoring
- Exported `Fetcher` interface
- Inject `Fetcher` to publicip loop and updaters
- Get public IP and information at the same time
- Only query ipinfo.io
- Make `MultiInfo` part of the `Fetch` object
2022-06-12 00:46:08 +00:00

57 lines
1.3 KiB
Go

package publicip
import (
"context"
"net"
"github.com/qdm12/gluetun/internal/publicip/models"
)
// FetchMultiInfo obtains the public IP address information for every IP
// addresses provided and returns a slice of results with the corresponding
// order as to the IP addresses slice order.
// If an error is encountered, all the operations are canceled and
// an error is returned, so the results returned should be considered
// incomplete in this case.
func (f *Fetch) FetchMultiInfo(ctx context.Context, ips []net.IP) (
results []models.IPInfoData, err error) {
ctx, cancel := context.WithCancel(ctx)
type asyncResult struct {
index int
result models.IPInfoData
err error
}
resultsCh := make(chan asyncResult)
for i, ip := range ips {
go func(index int, ip net.IP) {
aResult := asyncResult{
index: index,
}
aResult.result, aResult.err = f.FetchInfo(ctx, ip)
resultsCh <- aResult
}(i, ip)
}
results = make([]models.IPInfoData, len(ips))
for i := 0; i < len(ips); i++ {
aResult := <-resultsCh
if aResult.err != nil {
if err == nil {
// Cancel on the first error encountered
err = aResult.err
cancel()
}
continue // ignore errors after the first one
}
results[aResult.index] = aResult.result
}
close(resultsCh)
cancel()
return results, err
}