Skip to content

Instantly share code, notes, and snippets.

@jessta
Created February 20, 2012 16:25
Show Gist options
  • Save jessta/1869990 to your computer and use it in GitHub Desktop.
Save jessta/1869990 to your computer and use it in GitHub Desktop.
Remotely safely shutdown a Go HTTP server
package main
import "net/http"
import "net"
import "sync"
var lis net.Listener
func main(){
var err error
// make our own listener
lis, err = net.Listen("tcp",":8080")
if err != nil {
panic(err)
}
// make our own handler that puts all requests in a wait group.
h := &handler{ServeMux: http.NewServeMux()}
// add a close handlefunc to that handler
h.ServeMux.HandleFunc("/",close)
//listen and serve until listner is closed
http.Serve(lis,h)
//wait here until all current requests complete.
h.w.Wait()
}
type handler struct {
w sync.WaitGroup
*http.ServeMux
}
func (h *handler)ServeHTTP(w http.ResponseWriter, r *http.Request){
h.w.Add(1)
defer h.w.Done()
h.ServeMux.ServeHTTP(w, r)
//important to flush before decrementing the wait group.
//we won't get a chance to once main() ends.
w.(http.Flusher).Flush()
}
func close(w http.ResponseWriter, r *http.Request){
lis.Close()
w.Write([]byte("closed listener"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment