Skip to content

Instantly share code, notes, and snippets.

@kylelemons
Created July 23, 2011 01:40
Show Gist options
  • Save kylelemons/1100833 to your computer and use it in GitHub Desktop.
Save kylelemons/1100833 to your computer and use it in GitHub Desktop.
Send a bunch of HTTP requests via threads and goroutines
package main
import (
"fmt"
"http"
"flag"
"runtime"
"bytes"
"log"
)
var (
threads = flag.Int("threads", 1, "number of threads")
routines = flag.Int("goroutines", 1000, "number of goroutines")
count = flag.Int("count", 10, "number of HTTP goroutines per goroutine")
host = flag.String("host", "localhost:8080", "Hostname:port to connect to")
method = flag.String("method", "POST", "HTTP method to use")
path = flag.String("path", "/", "Path to request")
payload = flag.String("payload", "", "Payload of the request")
ctype = flag.String("content-type", "application/json", "Content-Type of payload")
)
func fetch(done chan<- bool) (okay bool) {
defer func() {
done <- okay
}()
url := &http.URL{
Scheme: "http",
Host: *host,
Path: *path,
}
if len(url.Path) == 0 || url.Path[0] != '/' {
url.Path = "/" + url.Path
}
body := bytes.NewBufferString(*payload)
req, err := http.NewRequest(*method, url.String(), body)
if err != nil {
log.Printf("newrequest: %s", err)
return false
}
if len(*payload) > 0 {
req.Header.Set("Content-Type", *ctype)
}
resp, err := http.DefaultTransport.RoundTrip(req)
if err != nil {
log.Printf("roundtrip: %s", err)
return false
}
if resp.StatusCode != 200 {
log.Printf("response: %s", resp.Status)
return false
}
return true
}
func main() {
flag.Parse()
runtime.GOMAXPROCS(*threads)
done := make(chan bool)
for i := 0; i < *routines; i++ {
go func() {
for j := 0; j < *count; j++ {
fetch(done)
}
}()
}
errors := 0
for i := 0; i < *routines * *count; i++ {
if !<-done {
errors++
}
}
fmt.Printf("%d requests transmitted, %d errors; %.2f%% error rate\n",
*routines * *count, errors, 100*float64(errors)/float64(*routines * *count))
}
@captn
Copy link

captn commented Aug 3, 2011

Interesting. The current Go tip works for -goroutines=1 -count=5000
but it crashes for e.g. -goroutines=500 -count=1
At first glance, I have no idea why. Did you filled some issue about this?

unexpected fault address 0x3ea776a0
throw: fault
[signal 0xb code=0x1 addr=0x3ea776a0 pc=0x7fef3e9767aa]
runtime.throw+0x40 /go-tip/src/pkg/runtime/runtime.c:110
runtime.throw(0x632cba, 0x3ea776a0)
runtime.sigpanic+0xe7 /go-tip/src/pkg/runtime/linux/thread.c:314
runtime.sigpanic()
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment