gobyexample/077-http-server-graceful-shutdown/http-server-graceful-shutdown.go
Mark McGranaghan e4b083d49b index work
2012-09-23 17:45:04 -07:00

95 lines
2.0 KiB
Go

// ## HTTP Serve Graceful Shutdown
package main
import (
"net"
"net/http"
"time"
"os"
"os/signal"
"syscall"
"fmt"
"sync/atomic"
)
func slow(res http.ResponseWriter, req *http.Request) {
fmt.Println("respond at=start")
time.Sleep(time.Second * 5)
res.Header().Set("Content-Type", "text/plain")
fmt.Fprintln(res, "Finally.")
fmt.Println("respond at=finish")
}
var connCount int64 = 0
type watchedConn struct {
net.Conn
}
func (w *watchedConn) Close() error {
atomic.AddInt64(&connCount, -1)
return w.Conn.Close()
}
type watchedListener struct {
net.Listener
}
func (l *watchedListener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept()
if err != nil {
return nil, err
}
atomic.AddInt64(&connCount, 1)
return &watchedConn{Conn: conn}, nil
}
func main() {
stop := make(chan bool, 1)
sig := make(chan os.Signal, 1)
server := &http.Server{Handler: http.HandlerFunc(slow)}
fmt.Println("listen at=start")
listener, listenErr := net.Listen("tcp", ":5000")
if listenErr != nil { panic(listenErr) }
wListener := &watchedListener{Listener: listener}
fmt.Println("listen at=finish")
go func() {
<- stop
fmt.Println("close at=start")
closeErr := wListener.Close()
if closeErr != nil { panic(closeErr) }
fmt.Println("close at=finish")
}()
go func() {
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("trap at=start")
<- sig
stop <- true
fmt.Println("trap at=finish")
}()
fmt.Println("serve at=start")
server.Serve(wListener)
fmt.Println("serve at=finish")
for {
connCountCurrent := atomic.LoadInt64(&connCount)
if connCountCurrent > 0 {
fmt.Println("wait at=pending remaining=", connCountCurrent)
time.Sleep(time.Second)
} else {
fmt.Println("wait at=finish remaining=", connCountCurrent)
return
}
}
}
// todo: clean up logging
// todo: limit shutdown time
// todo: factor out to cut-and-pastable against normal app
// todo: credit http://blog.nella.org/?p=879
// todo: comment about tcp servers