I have a method that returns Json from the database and it works correctly, however when I try to make it concurrent it does not return anything and does not give any errors. For example this is the method working correctly
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
db,err := sql.Open("DB_Connect")
if err != nil {
log.Fatal(err)
println(err)
}
var result string
errr := db.QueryRow("select json_build_object('Expiration', array_to_json(array_agg(t))) from (select fullname,ad_end from profiles where id=32)t").Scan(&result)
defer db.Close()
switch {
case errr != nil:
log.Fatal(errr)
}
fmt.Fprintf(w,result)
}
The above method works correctly and the data is returned to the browser then I try to make this method async
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
go func(){
db,err := sql.Open("DB_Connect")
if err != nil {
log.Fatal(err)
println(err)
}
var result string
errr := db.QueryRow("select json_build_object('Expiration', array_to_json(array_agg(t))) from (select fullname,ad_end from profiles where id=32)t").Scan(&result)
defer db.Close()
switch {
case errr != nil:
log.Fatal(errr)
}
fmt.Fprintf(w,result)
}()
}
The async above returns nothing the only thing I have changed is that I added the Go func() inside the method so that it is async and everything else is the same . I checked and the database is returning the same content back just have no idea why the async is not printing the results back to the browser.
The net/http server completes the response when the handler returns. Anything written to the response after the handler returns is ignored.
The handler function Listing_Expiration
is returning before the anonymous function executes fmt.Fprintf(w,result)
.
To fix this, use a sync.WaitGroup:
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
wg.Add(1)
go func(){
defer wg.Done()
// same code here as in question
}()
wg.Wait()
}
The net/http server starts a goroutine for each connection and runs handlers in those goroutines. If the code in the question is the complete handler, then there's no reason to start yet another goroutine.