github.com/minio/madmin-go@v1.7.5/perf-object.go (about) 1 // 2 // MinIO Object Storage (c) 2021 MinIO, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package madmin 18 19 import ( 20 "context" 21 "encoding/json" 22 "errors" 23 "net/http" 24 "net/url" 25 "strconv" 26 "time" 27 ) 28 29 // SpeedTestStatServer - stats of a server 30 type SpeedTestStatServer struct { 31 Endpoint string `json:"endpoint"` 32 ThroughputPerSec uint64 `json:"throughputPerSec"` 33 ObjectsPerSec uint64 `json:"objectsPerSec"` 34 Err string `json:"err"` 35 } 36 37 // SpeedTestStats - stats of all the servers 38 type SpeedTestStats struct { 39 ThroughputPerSec uint64 `json:"throughputPerSec"` 40 ObjectsPerSec uint64 `json:"objectsPerSec"` 41 Response Timings `json:"responseTime"` 42 TTFB Timings `json:"ttfb,omitempty"` 43 Servers []SpeedTestStatServer `json:"servers"` 44 } 45 46 // SpeedTestResult - result of the speedtest() call 47 type SpeedTestResult struct { 48 Version string `json:"version"` 49 Servers int `json:"servers"` 50 Disks int `json:"disks"` 51 Size int `json:"size"` 52 Concurrent int `json:"concurrent"` 53 PUTStats SpeedTestStats 54 GETStats SpeedTestStats 55 } 56 57 // SpeedtestOpts provide configurable options for speedtest 58 type SpeedtestOpts struct { 59 Size int // Object size used in speed test 60 Concurrency int // Concurrency used in speed test 61 Duration time.Duration // Total duration of the speed test 62 Autotune bool // Enable autotuning 63 StorageClass string // Choose type of storage-class to be used while performing I/O 64 Bucket string // Choose a custom bucket name while performing I/O 65 } 66 67 // Speedtest - perform speedtest on the MinIO servers 68 func (adm *AdminClient) Speedtest(ctx context.Context, opts SpeedtestOpts) (chan SpeedTestResult, error) { 69 if !opts.Autotune { 70 if opts.Duration <= time.Second { 71 return nil, errors.New("duration must be greater a second") 72 } 73 if opts.Size <= 0 { 74 return nil, errors.New("size must be greater than 0 bytes") 75 } 76 if opts.Concurrency <= 0 { 77 return nil, errors.New("concurrency must be greater than 0") 78 } 79 } 80 81 queryVals := make(url.Values) 82 if opts.Size > 0 { 83 queryVals.Set("size", strconv.Itoa(opts.Size)) 84 } 85 if opts.Duration > 0 { 86 queryVals.Set("duration", opts.Duration.String()) 87 } 88 if opts.Concurrency > 0 { 89 queryVals.Set("concurrent", strconv.Itoa(opts.Concurrency)) 90 } 91 if opts.Bucket != "" { 92 queryVals.Set("bucket", opts.Bucket) 93 } 94 if opts.Autotune { 95 queryVals.Set("autotune", "true") 96 } 97 resp, err := adm.executeMethod(ctx, 98 http.MethodPost, requestData{ 99 relPath: adminAPIPrefix + "/speedtest", 100 queryValues: queryVals, 101 }) 102 if err != nil { 103 return nil, err 104 } 105 if resp.StatusCode != http.StatusOK { 106 return nil, httpRespToErrorResponse(resp) 107 } 108 ch := make(chan SpeedTestResult) 109 go func() { 110 defer closeResponse(resp) 111 defer close(ch) 112 dec := json.NewDecoder(resp.Body) 113 for { 114 var result SpeedTestResult 115 if err := dec.Decode(&result); err != nil { 116 return 117 } 118 select { 119 case ch <- result: 120 case <-ctx.Done(): 121 return 122 } 123 } 124 }() 125 return ch, nil 126 }