Unknown
Unknown

Reputation: 393

How golang stop handler function if connection is lost

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

Answers (1)

minglwelld
minglwelld

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

Related Questions