Reputation: 393
It seems even if the connection is lost, the handler function is still running. For example, if I visit http://0.0.0.0:8000/home and close the browser suddenly, the screen will continue to print all the numbers.
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
http.HandleFunc("/home", func(w http.ResponseWriter, r *http.Request) {
i := 0
for {
fmt.Println("i", i)
i++
time.Sleep(time.Microsecond * 15)
}
})
http.ListenAndServe(":8000", nil)
}
related: How golang gin stop handler function immediately if connection is lost
Upvotes: 1
Views: 191
Reputation: 21
Option 1: Write on a disconnected connection returns an error. Break from the loop when fmt.Println returns an error.
func example(w http.ResponseWriter, r *http.Request) {
i := 0
for {
_, err := fmt.Println("i", i)
if err != nil {
return
}
i++
time.Sleep(time.Microsecond * 15)
}
}
Option 2: The server cancels the request context on disconnect. Loop while the context is not canceled.
func example(w http.ResponseWriter, r *http.Request) {
i := 0
c := r.Context()
for c.Err() == nil {
fmt.Println("i", i)
i++
time.Sleep(time.Microsecond * 15)
}
}
Option 3: The server cancels the request context on disconnect. Loop waiting for context cancelation or timer. Exit on cancelation.
func example(w http.ResponseWriter, r *http.Request) {
t := time.NewTicker(time.Microsecond * 15)
defer t.Stop()
done := r.Context().Done()
for {
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-t.C:
fmt.Println("Current time: ", t)
}
}
}
}
The handler will return earlier with option 3. Option 1 and 2 always wait for sleep to complete before handler returns.
Upvotes: 2