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 * updates forever
* no drm * no drm
= sources
* effective go
* chinese web apps book
* http://news.ycombinator.com/item?id=4543818
= topics = 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 * worker pool
* rate limiting * rate limiting
* string formatting
* web app
* time formatting * time formatting
* typed json parse/unparse * typed json parse/unparse
* gzip * gzip
@ -52,7 +65,9 @@ gobyexample.com signups
* oauth for google domains * oauth for google domains
* testing * testing
* markdown (blackfriday) * markdown (blackfriday)
* mongo * init functions
* using gofmt
* scrolls style logging
* setting up go env, hello world * setting up go env, hello world
* deploying to heroku * deploying to heroku
@ -66,3 +81,4 @@ command line client for public json api
redis server redis server
github webook receiver github webook receiver
campfire bot campfire bot
http://www.youtube.com/watch?v=-i0hat7pdpk

View File

@ -49,3 +49,7 @@ func main() {
} }
fmt.Println(area) 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 covers everything from getting started to writing sophisticated
concurrent programs. 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 You'll learn the basic of Go and how to build real-world programs
like database-backed web sites. like database-backed web sites.