Skip to content

Instantly share code, notes, and snippets.

@GeraldHost
Last active January 27, 2021 13:39
Show Gist options
  • Save GeraldHost/8cec08d76cb4f7f4e8b1b78cc56a735a to your computer and use it in GitHub Desktop.
Save GeraldHost/8cec08d76cb4f7f4e8b1b78cc56a735a to your computer and use it in GitHub Desktop.
http-benchmark
package main
import (
"github.com/valyala/fasthttp"
"net"
"os"
"sync"
"time"
"fmt"
)
type waitForConn struct {
// ready chan net.Conn
ready chan bool
mu sync.Mutex
}
type pool struct {
connsLock sync.Mutex
conns []net.Conn
dialer net.Dialer
connQueueLock sync.Mutex
connQueue []*waitForConn
size int
}
func (p *pool) aquireConn() net.Conn {
p.connsLock.Lock()
if n := len(p.conns); n > 0 {
conn := p.conns[0]
p.conns = p.conns[1:]
p.connsLock.Unlock()
return conn
}
p.connsLock.Unlock()
wc := waitForConn {
ready: make(chan bool, 1),
}
p.connQueueLock.Lock()
p.connQueue = append(p.connQueue, &wc)
p.connQueueLock.Unlock()
fmt.Println("waiting")
select {
case <-wc.ready:
fmt.Println("Ready")
return p.Dial()
}
}
func (p *pool) releaseConn(conn net.Conn) {
p.connsLock.Lock()
conns := p.conns
n := len(conns)
if n >= p.size {
conn.Close()
} else {
p.conns = append(p.conns, conn)
}
p.connsLock.Unlock()
p.connQueueLock.Lock()
fmt.Println("ll", len(p.connQueue))
if q := p.connQueue; len(q) > 0 {
for i:=0; i<len(q);i++ {
fmt.Println(1)
wc := q[i]
p.connQueue = nil
wc.ready <- true
fmt.Println(3)
}
p.connQueue = make([]*waitForConn)
}
p.connQueueLock.Unlock()
fmt.Println(4)
}
func (p *pool) Dial() net.Conn {
conn, err := p.dialer.Dial("tcp", "localhost:3000")
if err != nil {
os.Exit(1)
}
return conn
}
func NewPool(size int) pool {
p := pool{
dialer: net.Dialer{Timeout: 10 * time.Second},
conns: make([]net.Conn, size),
size: size,
}
for i := 0; i < size; i++ {
conn := p.Dial()
p.conns[i] = conn
}
return p
}
func DoReq(p *pool, wg *sync.WaitGroup) {
defer wg.Done()
conn := p.aquireConn()
buff := make([]byte, 12)
wn, werr := conn.Write([]byte("HEAD / HTTP/1.0\r\nAccept-Encoding: gzip\r\n\r\n"))
if werr != nil {
fmt.Println("WITE: ", werr, wn)
return
}
rn, rerr := conn.Read(buff)
if rerr != nil {
fmt.Println("READ: ", rerr, rn)
return
}
fmt.Println("releasing")
p.releaseConn(conn)
return
}
func main() {
var wg sync.WaitGroup
pool := NewPool(1)
for i := 0; i < 10; i++ {
wg.Add(1)
go DoReq(&pool, &wg)
}
wg.Wait()
}
// FAST HTTP BENCHMARK
func ExampleGetWithFastHttpManagedBuffers() {
url := "http://localhost:3000"
// Acquire a request instance
req := fasthttp.AcquireRequest()
defer fasthttp.ReleaseRequest(req)
req.SetRequestURI(url)
// Acquire a response instance
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp)
fasthttp.Do(req, resp)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment