graceful. not even mad

This commit is contained in:
Mark McGranaghan 2012-09-19 17:45:54 -07:00
parent 6c0386862a
commit 476a3bc84c
4 changed files with 112 additions and 4 deletions

24
README
View File

@ -33,12 +33,25 @@ gobyexample.com signups
* updates forever
* no drm
= sources
* effective go
* chinese web apps book
* http://news.ycombinator.com/item?id=4543818
= topics
* web app
* serve static files
* log requests
* basic auth
* force https
* force canonical host
* not found page
* error page
* graceful shutdown
* string formatting
* mongo
* worker pool
* rate limiting
* string formatting
* web app
* time formatting
* typed json parse/unparse
* gzip
@ -52,7 +65,9 @@ gobyexample.com signups
* oauth for google domains
* testing
* markdown (blackfriday)
* mongo
* init functions
* using gofmt
* scrolls style logging
* setting up go env, hello world
* deploying to heroku
@ -66,3 +81,4 @@ command line client for public json api
redis server
github webook receiver
campfire bot
http://www.youtube.com/watch?v=-i0hat7pdpk

View File

@ -49,3 +49,7 @@ func main() {
}
fmt.Println(area)
}
// == todo
// is this named wrong?
// note about embedding access

View 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

View File

@ -7,7 +7,9 @@ consisting of more than a hundred complete Go programs. The book
covers everything from getting started to writing sophisticated
concurrent programs.
Sign up to hear when an early release is ready:
[ you@domain.com]
You'll learn the basic of Go and how to build real-world programs
like database-backed web sites.