Maintenance: refactor servers updater code
- Require at least 80% of number of servers now to pass - Each provider is in its own package with a common structure - Unzip package with unzipper interface - Openvpn package with extraction and download functions
This commit is contained in:
59
internal/updater/openvpn/multifetch.go
Normal file
59
internal/updater/openvpn/multifetch.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package openvpn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// FetchMultiFiles fetches multiple Openvpn files in parallel and
|
||||
// parses them to extract each of their host. A mapping from host to
|
||||
// URL is returned.
|
||||
func FetchMultiFiles(ctx context.Context, client *http.Client, urls []string) (
|
||||
hostToURL map[string]string, err error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
hostToURL = make(map[string]string, len(urls))
|
||||
|
||||
type Result struct {
|
||||
url string
|
||||
host string
|
||||
}
|
||||
|
||||
results := make(chan Result)
|
||||
defer close(results)
|
||||
errors := make(chan error)
|
||||
defer close(errors)
|
||||
|
||||
for _, url := range urls {
|
||||
go func(url string) {
|
||||
host, err := FetchFile(ctx, client, url)
|
||||
if err != nil {
|
||||
errors <- err
|
||||
return
|
||||
}
|
||||
results <- Result{
|
||||
url: url,
|
||||
host: host,
|
||||
}
|
||||
}(url)
|
||||
}
|
||||
|
||||
for range urls {
|
||||
select {
|
||||
case newErr := <-errors:
|
||||
if err == nil { // only assign to the first error
|
||||
err = newErr
|
||||
cancel() // stop other operations, this will trigger other errors we ignore
|
||||
}
|
||||
case result := <-results:
|
||||
hostToURL[result.host] = result.url
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hostToURL, nil
|
||||
}
|
||||
Reference in New Issue
Block a user