From 476a3bc84c65b00fdfecb777c959dc9c87fbaff2 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Wed, 19 Sep 2012 17:45:54 -0700 Subject: [PATCH] graceful. not even mad --- README | 24 +++++-- src/34-embedding.go | 4 ++ src/xx-http-server-graceful-shutdown.go | 86 +++++++++++++++++++++++++ www/index.md | 2 + 4 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/xx-http-server-graceful-shutdown.go diff --git a/README b/README index 6aab25c..a058f10 100644 --- a/README +++ b/README @@ -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 diff --git a/src/34-embedding.go b/src/34-embedding.go index 544abca..290baf1 100644 --- a/src/34-embedding.go +++ b/src/34-embedding.go @@ -49,3 +49,7 @@ func main() { } fmt.Println(area) } + +// == todo +// is this named wrong? +// note about embedding access diff --git a/src/xx-http-server-graceful-shutdown.go b/src/xx-http-server-graceful-shutdown.go new file mode 100644 index 0000000..b556a22 --- /dev/null +++ b/src/xx-http-server-graceful-shutdown.go @@ -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 diff --git a/www/index.md b/www/index.md index b34a326..1061241 100644 --- a/www/index.md +++ b/www/index.md @@ -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.