Added benchmark for measuring the maximum client throughput

This commit is contained in:
Aliaksandr Valialkin
2015-11-13 19:38:46 +02:00
parent 6edf440c99
commit 69f3c67fce
3 changed files with 93 additions and 13 deletions
+10 -13
View File
@@ -320,13 +320,7 @@ func clientPostURL(dst []byte, url string, postArgs *Args, c clientDoer) (status
}
func doRequest(req *Request, dst []byte, url string, c clientDoer) (statusCode int, body []byte, err error) {
v := urlBufPool.Get()
if v == nil {
v = make([]byte, 1024)
}
buf := v.([]byte)
buf = AppendBytesStr(buf[:0], url)
req.Header.RequestURI = buf
req.SetRequestURI(url)
resp := acquireResponse()
resp.Body = dst
@@ -338,15 +332,10 @@ func doRequest(req *Request, dst []byte, url string, c clientDoer) (statusCode i
resp.Body = nil
releaseResponse(resp)
req.Header.RequestURI = nil
urlBufPool.Put(v)
return statusCode, body, err
}
var (
urlBufPool sync.Pool
requestPool sync.Pool
responsePool sync.Pool
)
@@ -392,7 +381,10 @@ func (c *HostClient) Do(req *Request, resp *Response) error {
if len(req.Header.host) == 0 {
req.Header.host = append(req.Header.host[:0], host...)
}
req.Header.RequestURI = req.URI.AppendRequestURI(req.Header.RequestURI[:0])
req.Header.clientBuf = req.URI.AppendRequestURI(req.Header.clientBuf[:0])
requestURIOld := req.Header.RequestURI
req.Header.RequestURI = req.Header.clientBuf
userAgentOld := req.Header.userAgent
if len(userAgentOld) == 0 {
@@ -401,6 +393,10 @@ func (c *HostClient) Do(req *Request, resp *Response) error {
cc, err := c.acquireConn()
if err != nil {
req.Header.RequestURI = requestURIOld
if len(userAgentOld) == 0 {
req.Header.userAgent = userAgentOld
}
return err
}
conn := cc.c
@@ -408,6 +404,7 @@ func (c *HostClient) Do(req *Request, resp *Response) error {
bw := c.acquireWriter(conn)
err = req.Write(bw)
req.Header.RequestURI = requestURIOld
if len(userAgentOld) == 0 {
req.Header.userAgent = userAgentOld
}
+80
View File
@@ -1,14 +1,94 @@
package fasthttp
import (
"bytes"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"sync"
"testing"
"time"
)
type fakeClientConn struct {
net.Conn
s []byte
n int
v interface{}
}
func (c *fakeClientConn) Write(b []byte) (int, error) {
return len(b), nil
}
func (c *fakeClientConn) Read(b []byte) (int, error) {
n := 0
for len(b) > 0 {
if c.n == len(c.s) {
c.n = 0
return n, nil
}
n = copy(b, c.s[c.n:])
c.n += n
b = b[n:]
}
return n, nil
}
func (c *fakeClientConn) Close() error {
releaseFakeServerConn(c)
return nil
}
func releaseFakeServerConn(c *fakeClientConn) {
c.n = 0
fakeClientConnPool.Put(c.v)
}
func acquireFakeServerConn(s []byte) *fakeClientConn {
v := fakeClientConnPool.Get()
if v == nil {
c := &fakeClientConn{
s: s,
}
c.v = c
return c
}
return v.(*fakeClientConn)
}
var fakeClientConnPool sync.Pool
func BenchmarkClientGetFastServer(b *testing.B) {
body := []byte("012345678912")
s := []byte(fmt.Sprintf("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s", len(body), body))
requestURI := []byte("http://foobar.com/aaa/bbb")
c := &Client{
Dial: func(addr string) (net.Conn, error) {
return acquireFakeServerConn(s), nil
},
}
b.RunParallel(func(pb *testing.PB) {
var req Request
var resp Response
req.Header.RequestURI = requestURI
for pb.Next() {
if err := c.Do(&req, &resp); err != nil {
b.Fatalf("unexpected error: %s", err)
}
if resp.Header.StatusCode != StatusOK {
b.Fatalf("unexpected status code: %d", resp.Header.StatusCode)
}
if !bytes.Equal(resp.Body, body) {
b.Fatalf("unexpected response body: %q. Expected %q", resp.Body, body)
}
}
})
}
func fasthttpEchoHandler(ctx *RequestCtx) {
ctx.Success("text/plain", ctx.Request.Header.RequestURI)
}
+3
View File
@@ -65,6 +65,9 @@ type RequestHeader struct {
bufKV argsKV
cookies []argsKV
// aux buffer for Client.
clientBuf []byte
}
// IsMethodGet returns true if request method is GET.