Skip to content

Commit

Permalink
Add timeout to testing mirrors. So at least one mirror will be select…
Browse files Browse the repository at this point in the history
…ed even if the others fail.
  • Loading branch information
taliesins committed Jul 2, 2015
1 parent a873c37 commit 152e4f9
Showing 1 changed file with 22 additions and 13 deletions.
35 changes: 22 additions & 13 deletions ubuntu/mirrors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ package ubuntu
import (
"bufio"
"errors"
"io"
"io/ioutil"
"log"
"net/http"
"time"
)

const (
mirrorsUrl = "http://mirrors.ubuntu.com/mirrors.txt"
benchmarkUrl = "dists/saucy/main/binary-amd64/Packages.bz2"
benchmarkUrl = "dists/trusty/Release"
benchmarkTimes = 3
benchmarkBytes = 1024 * 512 // 512Kb
benchmarkTimeout = 20 // 20 seconds
mirrorTimeout = 15 //seconds
)

type Mirrors struct {
Expand Down Expand Up @@ -43,6 +44,7 @@ func (m Mirrors) Fastest() (string, error) {
ch := make(chan benchmarkResult)

// kick off all benchmarks in parallel
log.Printf("Start benchmarking mirrors")
for _, url := range m.URLs {
go func(u string) {
duration, err := m.benchmark(u, benchmarkTimes)
Expand All @@ -51,19 +53,18 @@ func (m Mirrors) Fastest() (string, error) {
}
}(url)
}

readN := len(m.URLs)
if 3 < readN {
readN = 3
}

// wait for the fastest results to come back
results, err := m.readResults(ch, readN)
if len(results) == 0 {
log.Printf("Finished benchmarking mirrors")
if len(results) == 0 {
return "", errors.New("No results found: " + err.Error())
} else if err != nil {
log.Printf("Error benchmarking mirrors: %s", err.Error())
}
}

return results[0].URL, nil
}
Expand All @@ -73,8 +74,9 @@ func (m Mirrors) readResults(ch <-chan benchmarkResult, size int) (br []benchmar
select {
case r := <-ch:
br = append(br, r)
if len(br) == size {
return

if len(br) >= size {
return br, nil
}
case <-time.After(benchmarkTimeout * time.Second):
return br, errors.New("Timed out waiting for results")
Expand All @@ -86,21 +88,28 @@ func (m Mirrors) benchmark(url string, times int) (time.Duration, error) {
var sum int64
var d time.Duration
url = url + benchmarkUrl

timeout := time.Duration(mirrorTimeout * time.Second)
client := http.Client{
Timeout: timeout,
}

for i := 0; i < times; i++ {
timer := time.Now()
response, err := http.Get(url)

response, err := client.Get(url)
if err != nil {
return d, err
}

_, err = io.ReadAtLeast(response.Body, make([]byte, benchmarkBytes), benchmarkBytes)

defer response.Body.Close()
_, err = ioutil.ReadAll(response.Body)

if err != nil {
return d, err
}

sum = sum + int64(time.Since(timer))
response.Body.Close()
}

return time.Duration(sum / int64(times)), nil
Expand Down

0 comments on commit 152e4f9

Please sign in to comment.