Files
old-vegeta/client.go
2013-08-16 20:08:10 +02:00

61 lines
1.4 KiB
Go

package main
import (
"errors"
"io/ioutil"
"net/http"
"time"
)
// Client is an http.Client with rate limiting
// TODO: Add timeouts
type Client struct {
http.Client
rate uint64
}
// Response represents the metrics we want out of an http.Response
type Response struct {
code uint64
timestamp time.Time
timing time.Duration
bytesOut uint64
bytesIn uint64
err error
}
// NewClient returns an initialized Client
func NewClient(rate uint64) *Client {
return &Client{http.Client{}, rate}
}
// Drill loops over the passed reqs channel and executes each request.
// It is throttled to the rate specified in the initializer
func (c *Client) Drill(reqs chan *http.Request, res chan *Response) {
throttle := time.Tick(time.Duration(1e9 / c.rate))
for req := range reqs {
<-throttle
go c.Do(req, res)
}
}
// Do executes the passed http.Request and puts a generated *Response into res.
func (c *Client) Do(req *http.Request, res chan *Response) {
began := time.Now()
r, err := c.Client.Do(req)
resp := &Response{
timestamp: began,
timing: time.Since(began),
bytesOut: uint64(req.ContentLength),
err: err,
}
if err == nil {
resp.bytesIn, resp.code = uint64(r.ContentLength), uint64(r.StatusCode)
if body, err := ioutil.ReadAll(r.Body); err != nil && resp.code < 200 || resp.code >= 300 {
resp.err = errors.New(string(body))
}
}
res <- resp
}