一定時間だけ立ち上がって自動的に終了するサーバーをGoで書いてみた。
あんまり用途はないのかもしれないが、例えばcronで毎日0:00から5分だけ立ち上がっていてそこにアクセスしてサーバーメトリクスを収集するみたいな使い方が出来るかもしれない。
いちおうコードの解説。
main関数のところだけコードをの詳細を書いてみる。
まずはじめに、runServer()
でサーバーを立ち上げる。
次に、 time.Tick t
で一定時間経過後にシグナルを送るようなselectループを作成する。
time.Tick et
はただのデバッグ用のコードなので削除しても構わない。
最後に、 チャネル ch
で入力を待って終了する。
func main() { go runServer() t := time.Tick(time.Duration(duration) * time.Second) et := time.Tick(time.Duration(1) * time.Second) go func() { for { select { case <-t: ch <- true case <-et: // debug code fmt.Printf("[%d] server running!\n", time.Now().Unix()) } } }() _ = <-ch fmt.Println("Finished.") }
試しに、3秒で終了するように動かしてた結果がこんな感じ。
きっちり、3回デバッグ用のコードが出力されて終了している。
% go run hey_server.go -duration=3 [1446923055] server running! [1446923056] server running! [1446923057] server running! Finished.
以下、コード全体。
package main import ( "flag" "fmt" "log" "net/http" "time" ) type BaseHandler struct { Name string } func (bh *BaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if bh.Name != "" { fmt.Fprint(w, "Hey "+bh.Name+"!") } else { fmt.Fprint(w, "Hey World!") } } func runServer() { mux := http.NewServeMux() bh := &BaseHandler{Name: name} mux.Handle("/hey", bh) addr := fmt.Sprintf(":%d", 8080) err := http.ListenAndServe(addr, mux) if err != nil { log.Fatal(err) } } var ch = make(chan bool) var name string var duration int func init() { flag.StringVar(&name, "name", "", "your name") flag.IntVar(&duration, "duration", 60, "working time") flag.Parse() } func main() { go runServer() t := time.Tick(time.Duration(duration) * time.Second) et := time.Tick(time.Duration(1) * time.Second) go func() { for { select { case <-t: ch <- true case <-et: // debug code fmt.Printf("[%d] server running!\n", time.Now().Unix()) } } }() _ = <-ch fmt.Println("Finished.") } // https://gobyexample.com/select