package main
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"sync"
"time"
)
func arrayToString(A []time.Duration, delim string) string {
var buffer bytes.Buffer
for i := 0; i < len(A); i++ {
buffer.WriteString(strconv.FormatInt(A[i].Milliseconds(), 10))
if i != len(A)-1 {
buffer.WriteString(delim)
}
}
return buffer.String()
}
type Request struct {
url string
method string
}
type Client struct {
httpClient *http.Client
request Request
}
type Result struct {
id int64
durations []time.Duration
mu sync.Mutex
}
func (r *Result) addResult(duration time.Duration) {
r.mu.Lock()
defer r.mu.Unlock()
r.durations = append(r.durations, duration)
}
func (r *Result) reset(id int64) {
r.id = id
r.durations = []time.Duration{}
}
func (r *Result) print() {
fmt.Printf("%d,%s\r\n", r.id, arrayToString(r.durations, ","))
}
func NewClient(request Request) *Client {
return &Client{
httpClient: &http.Client{
Timeout: time.Second * 5,
},
request: request,
}
}
func (c *Client) Send() (time.Duration, error) {
start := time.Now()
req, err := http.NewRequest(c.request.method, c.request.url, nil)
if err != nil {
return 0, err
}
res, err := c.httpClient.Do(req)
if err != nil {
return 0, err
}
_, err = ioutil.ReadAll(res.Body)
return time.Since(start), nil
}
func main() {
var batchSize int
var count int
var endpoint string
var interval int
flag.StringVar(&endpoint, "url", "", "url to multi send too")
flag.IntVar(&batchSize, "batchSize", 0, "number of orders to send in a batch")
flag.IntVar(&count, "count", 0, "number of attempts")
flag.IntVar(&interval, "interval", 0, "attempt interval in ms")
flag.Parse()
req := Request{
url: endpoint,
method: http.MethodGet,
}
client := NewClient(req)
result := Result{
id: 0,
durations: make([]time.Duration, 0),
}
var wg sync.WaitGroup
for i := int64(0); i < int64(count); i++ {
result.reset(i + 1)
for j := 0; j < batchSize; j++ {
wg.Add(1)
go func(result *Result) {
defer wg.Done()
if duration, err := client.Send(); err == nil {
result.addResult(duration)
}
}(&result)
}
wg.Wait()
result.print()
time.Sleep(time.Millisecond * time.Duration(interval))
}
}