Created
October 5, 2017 15:47
-
-
Save koron/8ae9d2e27182f145466ce5794af7c01e to your computer and use it in GitHub Desktop.
Sample http.Server with Shutdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"log" | |
"net/http" | |
"os" | |
"os/signal" | |
"time" | |
) | |
func serve() error { | |
// サーバーの準備 | |
http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { | |
w.Write([]byte("Hello, example http server\n")) | |
}) | |
s := http.Server{Addr: ":8080"} | |
// goroutine 間通信のためのチャンネルの作成とその後片付けを予約 | |
sig := make(chan os.Signal, 1) | |
cherr := make(chan error, 1) | |
defer func() { | |
close(cherr) | |
close(sig) | |
}() | |
// シグナルモニタリングのループ | |
go func() { | |
for { | |
s := <-sig | |
if s == os.Interrupt { | |
break | |
} | |
} | |
signal.Stop(sig) | |
// シャットダウンを無限に待っても良いけど、 | |
// 15秒でタイムアウトするようにした | |
ctx, _ := context.WithTimeout(context.Background(), 15*time.Second) | |
err := s.Shutdown(ctx) | |
if err == nil { | |
// 綺麗に終わったらログを出す | |
log.Printf("shutdown HTTP server gracefully") | |
} | |
cherr <- err | |
}() | |
// シグナルを受け付け始めてサーバーを起動 | |
signal.Notify(sig, os.Interrupt) | |
err := s.ListenAndServe() | |
if err == http.ErrServerClosed { | |
// シャットダウンされた場合はその完了を待ち、そちらのエラーを返す | |
return <-cherr | |
} | |
// それ以外はサーバーが返したエラーをそのまま返す | |
return err | |
} | |
func main() { | |
err := serve() | |
if err != nil { | |
// サーバーがエラー返したらログに吐く | |
log.Print(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment