Background measurements and report progress to user with spinner! master
authorJacob Casper <dev@jacobcasper.com>
Fri, 28 Jun 2024 01:08:10 +0000 (20:08 -0500)
committerJacob Casper <dev@jacobcasper.com>
Fri, 28 Jun 2024 01:08:10 +0000 (20:08 -0500)
main.go

diff --git a/main.go b/main.go
index 0487062..0ca426f 100644 (file)
--- a/main.go
+++ b/main.go
@@ -8,6 +8,7 @@ import (
        "log"
        "net/http"
        "net/url"
+       "sort"
        "strconv"
        "time"
 )
@@ -55,15 +56,57 @@ func main() {
                URL:    dUrl,
        }
 
+       downRates := make([]float64, 0)
+       upRates := make([]float64, 0)
+       downChan := make(chan float64)
+       upChan := make(chan float64)
+
        client := &http.Client{}
-       for i := 0; i < iter; i++ {
-               rate := measureRequest(client, down, measurementBytes)
-               fmt.Printf("Down: MiB/s %v\n", rate/MiB)
+       go measureNRequests(iter, client, func() *http.Request { return down }, bytes, downChan)
+       go measureNRequests(iter, client, func() *http.Request { return getUp(uUrl, bytes) }, bytes, upChan)
+       tickChan := make(chan rune)
+       go func() {
+               for {
+                       for _, char := range "|/-\\" {
+                               time.Sleep(100 * time.Millisecond)
+                               tickChan <- char
+                       }
+               }
+       }()
+
+downChannel:
+       for {
+               select {
+               case rate, ok := <-downChan:
+                       if !ok {
+                               fmt.Println("\rRunning download tests: done!")
+                               break downChannel
+                       }
+                       downRates = append(downRates, rate)
+               case spinner := <-tickChan:
+                       fmt.Printf("\rRunning download tests: %c", spinner)
+               }
        }
-       for i := 0; i < iter; i++ {
-               rate := measureRequest(client, getUp(uUrl, measurementBytes), measurementBytes)
-               fmt.Printf("Up: MiB/s %v\n", rate/MiB)
+
+upChannel:
+       for {
+               select {
+               case rate, ok := <-upChan:
+                       if !ok {
+                               fmt.Println("\rRunning upload tests: done!")
+                               break upChannel
+                       }
+                       upRates = append(upRates, rate)
+               case spinner := <-tickChan:
+                       fmt.Printf("\rRunning upload tests: %c", spinner)
+               }
        }
+
+       sort.Sort(sort.Float64Slice(downRates))
+       sort.Sort(sort.Float64Slice(upRates))
+
+       fmt.Printf("Down 90pctl: MiB/s %v\n", downRates[8]/float64(MiB))
+       fmt.Printf("Up 90pctl: MiB/s %v\n", upRates[8]/float64(MiB))
 }
 
 // Can't figure out how to reset r on each request so unfortunately just reinstantiate :/
@@ -80,6 +123,15 @@ func getUp(url *url.URL, measurement Byte) *http.Request {
        }
 }
 
+type requestGetter func() *http.Request
+
+func measureNRequests(n int, client *http.Client, r requestGetter, b Byte, ch chan float64) {
+       for i := 0; i < n; i++ {
+               ch <- measureRequest(client, r(), b)
+       }
+       close(ch)
+}
+
 // Returns the rate in bytes / s
 func measureRequest(client *http.Client, r *http.Request, b Byte) float64 {
        var start = time.Now()