一定時間だけ立ち上がって自動的に終了するサーバーを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