/
server.go
94 lines (77 loc) · 1.73 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"
goCache "github.com/pmylund/go-cache"
)
func cacheFetcher(c *goCache.Cache) {
fmt.Println("cacheFetch!!")
time.Sleep(10 * time.Second)
fmt.Println("cacheFetched!!")
}
func main() {
fd := flag.Uint("fd", 0, "fd to listen and serve")
port := flag.Uint("port", 3001, "port to listen and serve")
flag.Parse()
c := goCache.New(5*time.Minute, 30*time.Second)
// まずキャッシュを取る
// ここを goroutine にしないことで準備ができるまでファイルディスクリプタをListenしないのでリクエストが来ない
cacheFetcher(c)
interval := time.Tick(30 * time.Second)
go func() {
for {
<-interval
cacheFetcher(c)
}
}()
cs := make(chan os.Signal, 1)
ec := make(chan int)
signal.Notify(cs, syscall.SIGTERM, syscall.SIGINT)
go func() {
for {
switch <-cs {
// circusctl reload は SIGTERM を送る
case syscall.SIGTERM:
fmt.Println("SIGTERM!!")
time.Sleep(20 * time.Second)
fmt.Println("SIGTERM!!!")
ec <- 0
case syscall.SIGINT:
ec <- 0
}
}
}()
go func() {
for i := 0; ; i++ {
time.Sleep(200 * time.Millisecond)
fmt.Printf("%d\n", i)
}
}()
http.HandleFunc("/app_check", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusTeapot)
})
var l net.Listener
var err error
if *fd == 0 {
log.Println(fmt.Sprintf("listening on port %d", *port))
l, err = net.ListenTCP("tcp", &net.TCPAddr{Port: int(*port)})
} else {
log.Println("listening on socket")
l, err = net.FileListener(os.NewFile(uintptr(*fd), ""))
}
if err != nil {
log.Fatal(err)
panic(err)
}
go func() {
log.Println(http.Serve(l, nil))
}()
<-ec
}