I have a simple code that retrieves data from the database and I am using Jmeter to perform load testing on it . What I am doing is simulating 1,000 requests sometimes I get all 1,000 successful requests and other times I get 999 requests and I have to stop it because it seems like the thread or last results keeps on going indefinitely this is how it looks, notice on how the last request takes more than 10 times the normal time . If i don't stop it then that request would keep going on and on .
This is my code
func get_data(w http.ResponseWriter, r *http.Request) {
var result string
r.ParseForm()
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
db.QueryRow("select json_build_object('Locations', array_to_json(array_agg(t))) from (SELECT latitudes,county,longitudes,"+
"statelong,thirtylatmin,thirtylatmax,thirtylonmin,thirtylonmax,city"+
" FROM zips where city='Orlando' ORDER BY city limit 5) t").Scan(&result)
}()
wg.Wait()
fmt.Fprintf(w,result)
}
Then I have my database connection
var db *sql.DB
func init() {
var err error
db, err = sql.Open("postgres", Postgres_Connect)
if err != nil {
log.Fatal("Invalid DB config:", err)
println("Invalid DB config:")
//log_errors("HomePage-Postgres: error opening database",err)
}
if err = db.Ping(); err != nil {
log.Fatal("DB unreachable:", err)
println()
}
}
and here is my HTTP server
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
r := mux.NewRouter()
r.HandleFunc("/mydata",Controllers.Get_Data)
http.Handle("/",r)
srv := &http.Server{
ReadTimeout: 20 * time.Second,
WriteTimeout: 20 * time.Second,
IdleTimeout: 120 * time.Second,
Addr: ":8000",
}
log.Println(srv.ListenAndServe())
}
I was hoping that the ReadTimeOut would kill the connection but it seems like it doesn't
ReadTimeOut
applies to the reads made by net/http
's server code, not to the goroutine executing the request:
ReadTimeout is the maximum duration for reading the entire request, including the body.`
Once the request has been read this value is no longer used, and the handler is in charge of deciding whether or not things have timed out.
If you want to cancel the HTTP request before the database query is done, you can do this with a context.Context.
Extend req.Context
, add a timeout or deadline, passing this new context to sql.QueryRowContext
:
ctx, _ := context.WithTimeout( r.Context(), 20 * time.Second )
db.QueryRowContext(ctx, "select json_build_object('Locations', array_to_json(array_agg(t))) from (SELECT latitudes,county,longitudes,"+
"statelong,thirtylatmin,thirtylatmax,thirtylonmin,thirtylonmax,city"+
" FROM zips where city='Orlando' ORDER BY city limit 5) t").Scan(&result)