Reputation: 20409
I have the following code:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
player.Exec(command, func(response map[string]interface{}){
if response["statusCode"]==float64(0) { // ok
w.Write([]byte(response["statusMessage"].(string)))
player.SendMessage("<b>"+response["statusMessage"].(string)+"</b>")
fmt.Println("playerExec: "+time.Now().Format("20060102150405"))
} else { // failed to process
w.WriteHeader(http.StatusBadRequest) // 400
w.Write([]byte(response["statusMessage"].(string)))
player.SendMessage(response["statusMessage"].(string))
}
})
// Time.Sleep(Time.Seconds*2)
fmt.Println("cmd: "+time.Now().Format("20060102150405"))
})
processing of player.Exec()
takes some time (since it initiates WebSocket connection), so the callback function is called after some time (see proofs below). It is late, so I see the following error:
http: superfluous response.WriteHeader call from main.main.func1.1
Also, when I open the '/' page in the browser, I see no content.
If I add Time.Sleep()
to my code (see the commented line), then I see the content.
The Exec() code is here.
The log shows the following -
cmd: 20200612192659
playerExec: 20200612192659
Is there any way to wait for the callback function return?
Upvotes: 0
Views: 1320
Reputation: 491
Yes, you can use sync.WaitGroup
as follows:
wg := sync.WaitGroup{}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
wg.Add(1) // add a waitgroup before calling the async function
player.Exec(command, func(response map[string]interface{}){
defer wg.Done() // release when this function returns
if response["statusCode"]==float64(0) { // ok
w.Write([]byte(response["statusMessage"].(string)))
player.SendMessage("<b>"+response["statusMessage"].(string)+"</b>")
fmt.Println("playerExec: "+time.Now().Format("20060102150405"))
} else { // failed to process
w.WriteHeader(http.StatusBadRequest) // 400
w.Write([]byte(response["statusMessage"].(string)))
player.SendMessage(response["statusMessage"].(string))
}
})
wg.Wait() // this will block until all the resources are released
fmt.Println("cmd: "+time.Now().Format("20060102150405"))
})
Upvotes: 2
Reputation: 825
http: superfluous response.WriteHeader call from main.main.func1.1
You will see this if you do a WriteHeader
after you have already written something to the response via Write
. That's why WriteHeader is extra or superfluous
.
As of waiting for your exec to be done, you can use waitgroup in your closure.
wg.Wait()
will wait until your exec callback has returned
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
wg.Add(1)
player.Exec(command, func(response map[string]interface{}){
defer wg.Done()
if response["statusCode"]==float64(0) { // ok
w.Write([]byte(response["statusMessage"].(string)))
player.SendMessage("<b>"+response["statusMessage"].(string)+"</b>")
fmt.Println("playerExec: "+time.Now().Format("20060102150405"))
} else { // failed to process
w.WriteHeader(http.StatusBadRequest) // 400
w.Write([]byte(response["statusMessage"].(string)))
player.SendMessage(response["statusMessage"].(string))
}
})
wg.Wait()
// Time.Sleep(Time.Seconds*2)
fmt.Println("cmd: "+time.Now().Format("20060102150405"))
})
Upvotes: 0