From 97d621d4169aea6e24efef12a9cc52a0ed13413d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 28 Aug 2023 13:50:32 +0200 Subject: [PATCH 1/5] feat(perf): support iperf-style intermittent results Required for https://github.com/libp2p/test-plans/issues/261. --- client.go | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index 23183d6..7cd0fa6 100644 --- a/client.go +++ b/client.go @@ -14,7 +14,10 @@ import ( ) type Result struct { - Latency float64 `json:"latency"` + Type string `json:"type"` + TimeSeconds float64 `json:"timeSeconds"` + UploadBytes uint `json:"uploadBytes"` + DownloadBytes uint `json:"downloadBytes"` } func RunClient(addr string, uploadBytes, downloadBytes uint64) error { @@ -44,7 +47,10 @@ func RunClient(addr string, uploadBytes, downloadBytes uint64) error { log.Printf("uploaded %s: %.2fs (%s/s)", formatBytes(uploadBytes), uploadTook.Seconds(), formatBytes(bandwidth(uploadBytes, uploadTook))) log.Printf("downloaded %s: %.2fs (%s/s)", formatBytes(downloadBytes), downloadTook.Seconds(), formatBytes(bandwidth(downloadBytes, downloadTook))) json, err := json.Marshal(Result{ - Latency: time.Since(start).Seconds(), + TimeSeconds: time.Since(start).Seconds(), + Type: "final", + UploadBytes: uint(uploadBytes), + DownloadBytes: uint(downloadBytes), }) if err != nil { return err @@ -63,7 +69,28 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 // upload data b = make([]byte, 16*1024) uploadStart := time.Now() + + lastReportTime := time.Now() + lastReportWrite := 0 + for uploadBytes > 0 { + // TODO: Is this expensive in go? Is there a cheaper API with less resolution? + now := time.Now() + if now.Sub(lastReportTime) > time.Second { + jsonB, err := json.Marshal(Result{ + TimeSeconds: now.Sub(lastReportTime).Seconds(), + UploadBytes: uint(lastReportWrite), + Type: "intermediary", + }) + if err != nil { + log.Fatalf("failed to marshal perf result: %s", err) + } + fmt.Println(string(jsonB)) + + lastReportTime = now + lastReportWrite = 0 + } + if uploadBytes < uint64(len(b)) { b = b[:uploadBytes] } @@ -72,7 +99,9 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 return 0, 0, err } uploadBytes -= uint64(n) + lastReportWrite += n } + if err := str.Close(); err != nil { return 0, 0, err } From afe8ce9889f8ae0dd08e7d77faadaa13d46d8779 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 15 Sep 2023 19:39:24 +0200 Subject: [PATCH 2/5] Print on read --- client.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/client.go b/client.go index 7cd0fa6..aba038e 100644 --- a/client.go +++ b/client.go @@ -111,12 +111,33 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 b = b[:cap(b)] remaining := downloadBytes downloadStart := time.Now() + + lastReportTime = time.Now() + lastReportRead := 0 + for remaining > 0 { + now := time.Now() + if now.Sub(lastReportTime) > time.Second { + jsonB, err := json.Marshal(Result{ + TimeSeconds: now.Sub(lastReportTime).Seconds(), + DownloadBytes: uint(lastReportRead), + Type: "intermediary", + }) + if err != nil { + log.Fatalf("failed to marshal perf result: %s", err) + } + fmt.Println(string(jsonB)) + + lastReportTime = now + lastReportRead = 0 + } + n, err := str.Read(b) if uint64(n) > remaining { return 0, 0, fmt.Errorf("server sent more data than expected, expected %d, got %d", downloadBytes, remaining+uint64(n)) } remaining -= uint64(n) + lastReportRead += n if err != nil { if err == io.EOF { if remaining == 0 { From 9cc8712a6c76fcb7a1dcf099c22f75d6a822a8c5 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 25 Sep 2023 09:42:23 +0200 Subject: [PATCH 3/5] go fmt --- client.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index 62f7f6b..539ac02 100644 --- a/client.go +++ b/client.go @@ -48,9 +48,9 @@ func RunClient(addr string, uploadBytes, downloadBytes uint64, keyLogFile io.Wri log.Printf("uploaded %s: %.2fs (%s/s)", formatBytes(uploadBytes), uploadTook.Seconds(), formatBytes(bandwidth(uploadBytes, uploadTook))) log.Printf("downloaded %s: %.2fs (%s/s)", formatBytes(downloadBytes), downloadTook.Seconds(), formatBytes(bandwidth(downloadBytes, downloadTook))) json, err := json.Marshal(Result{ - TimeSeconds: time.Since(start).Seconds(), - Type: "final", - UploadBytes: uint(uploadBytes), + TimeSeconds: time.Since(start).Seconds(), + Type: "final", + UploadBytes: uint(uploadBytes), DownloadBytes: uint(downloadBytes), }) if err != nil { @@ -75,13 +75,12 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 lastReportWrite := 0 for uploadBytes > 0 { - // TODO: Is this expensive in go? Is there a cheaper API with less resolution? now := time.Now() if now.Sub(lastReportTime) > time.Second { jsonB, err := json.Marshal(Result{ TimeSeconds: now.Sub(lastReportTime).Seconds(), UploadBytes: uint(lastReportWrite), - Type: "intermediary", + Type: "intermediary", }) if err != nil { log.Fatalf("failed to marshal perf result: %s", err) @@ -120,9 +119,9 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 now := time.Now() if now.Sub(lastReportTime) > time.Second { jsonB, err := json.Marshal(Result{ - TimeSeconds: now.Sub(lastReportTime).Seconds(), + TimeSeconds: now.Sub(lastReportTime).Seconds(), DownloadBytes: uint(lastReportRead), - Type: "intermediary", + Type: "intermediary", }) if err != nil { log.Fatalf("failed to marshal perf result: %s", err) From 59d4b60c3ba1786a717ce3d8dceea8618a975af6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 26 Sep 2023 16:55:12 +0200 Subject: [PATCH 4/5] Apply code review comments --- client.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/client.go b/client.go index 539ac02..4edc558 100644 --- a/client.go +++ b/client.go @@ -16,8 +16,8 @@ import ( type Result struct { Type string `json:"type"` TimeSeconds float64 `json:"timeSeconds"` - UploadBytes uint `json:"uploadBytes"` - DownloadBytes uint `json:"downloadBytes"` + UploadBytes uint64 `json:"uploadBytes"` + DownloadBytes uint64 `json:"downloadBytes"` } func RunClient(addr string, uploadBytes, downloadBytes uint64, keyLogFile io.Writer) error { @@ -50,8 +50,8 @@ func RunClient(addr string, uploadBytes, downloadBytes uint64, keyLogFile io.Wri json, err := json.Marshal(Result{ TimeSeconds: time.Since(start).Seconds(), Type: "final", - UploadBytes: uint(uploadBytes), - DownloadBytes: uint(downloadBytes), + UploadBytes: uploadBytes, + DownloadBytes: downloadBytes, }) if err != nil { return err @@ -72,14 +72,14 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 uploadStart := time.Now() lastReportTime := time.Now() - lastReportWrite := 0 + lastReportWrite := uint64(0) for uploadBytes > 0 { now := time.Now() - if now.Sub(lastReportTime) > time.Second { + if now.Sub(lastReportTime) >= time.Second { jsonB, err := json.Marshal(Result{ TimeSeconds: now.Sub(lastReportTime).Seconds(), - UploadBytes: uint(lastReportWrite), + UploadBytes: lastReportWrite, Type: "intermediary", }) if err != nil { @@ -99,7 +99,7 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 return 0, 0, err } uploadBytes -= uint64(n) - lastReportWrite += n + lastReportWrite += uint64(n) } if err := str.Close(); err != nil { @@ -113,14 +113,14 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 downloadStart := time.Now() lastReportTime = time.Now() - lastReportRead := 0 + lastReportRead := uint64(0) for remaining > 0 { now := time.Now() - if now.Sub(lastReportTime) > time.Second { + if now.Sub(lastReportTime) >= time.Second { jsonB, err := json.Marshal(Result{ TimeSeconds: now.Sub(lastReportTime).Seconds(), - DownloadBytes: uint(lastReportRead), + DownloadBytes: lastReportRead, Type: "intermediary", }) if err != nil { @@ -137,7 +137,7 @@ func handleClientStream(str io.ReadWriteCloser, uploadBytes, downloadBytes uint6 return 0, 0, fmt.Errorf("server sent more data than expected, expected %d, got %d", downloadBytes, remaining+uint64(n)) } remaining -= uint64(n) - lastReportRead += n + lastReportRead += uint64(n) if err != nil { if err == io.EOF { if remaining == 0 { From 5202af6c72c6320a5b5b597e8b10ab45171499b3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 19 Oct 2023 11:11:15 +0200 Subject: [PATCH 5/5] go fmt --- client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index 4edc558..01e3237 100644 --- a/client.go +++ b/client.go @@ -16,8 +16,8 @@ import ( type Result struct { Type string `json:"type"` TimeSeconds float64 `json:"timeSeconds"` - UploadBytes uint64 `json:"uploadBytes"` - DownloadBytes uint64 `json:"downloadBytes"` + UploadBytes uint64 `json:"uploadBytes"` + DownloadBytes uint64 `json:"downloadBytes"` } func RunClient(addr string, uploadBytes, downloadBytes uint64, keyLogFile io.Writer) error {