graceful. not even mad
This commit is contained in:
@@ -49,3 +49,7 @@ func main() {
|
||||
}
|
||||
fmt.Println(area)
|
||||
}
|
||||
|
||||
// == todo
|
||||
// is this named wrong?
|
||||
// note about embedding access
|
||||
|
||||
86
src/xx-http-server-graceful-shutdown.go
Normal file
86
src/xx-http-server-graceful-shutdown.go
Normal file
@@ -0,0 +1,86 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// == running
|
||||
// $ cd src
|
||||
// $ go build xx-http-server-graceful-shutdown.go
|
||||
// $ ./xx-http-server-graceful-shutdown
|
||||
//
|
||||
// $ curl -i http://127.0.0.1:5000/
|
||||
//
|
||||
// ^C
|
||||
Reference in New Issue
Block a user