-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.go
103 lines (82 loc) · 1.94 KB
/
app.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
95
96
97
98
99
100
101
102
103
package winterfx
import (
"github.com/guoyk93/winterfx/core/probefx"
"github.com/guoyk93/winterfx/core/routerfx"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/fx"
"net/http"
_ "net/http/pprof"
"strings"
)
// App the main interface of [summer]
type App interface {
// Handler inherit [http.Handler]
http.Handler
}
type app struct {
*Params
probe probefx.Probe
router routerfx.Router
hProm http.Handler
}
func (a *app) serveReadiness(rw http.ResponseWriter, req *http.Request) {
c := routerfx.NewContext(rw, req)
defer c.Perform()
s, failed := a.probe.CheckReadiness(c)
status := http.StatusOK
if failed {
status = http.StatusInternalServerError
}
c.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
c.Code(status)
c.Text(s)
}
func (a *app) serveLiveness(rw http.ResponseWriter, req *http.Request) {
c := routerfx.NewContext(rw, req)
defer c.Perform()
c.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
if a.probe.CheckLiveness() {
c.Code(http.StatusInternalServerError)
c.Text("CASCADED FAILURE")
} else {
c.Code(http.StatusOK)
c.Text("OK")
}
}
func (a *app) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// alive, ready, metrics
if req.URL.Path == a.PathReadiness {
// support readinessPath == livenessPath
a.serveReadiness(rw, req)
return
} else if req.URL.Path == a.PathLiveness {
a.serveLiveness(rw, req)
return
} else if req.URL.Path == a.PathMetrics {
a.hProm.ServeHTTP(rw, req)
return
}
// pprof
if strings.HasPrefix(req.URL.Path, "/debug/pprof") {
http.DefaultServeMux.ServeHTTP(rw, req)
return
}
// serve with main handler
a.router.ServeHTTP(rw, req)
}
type Options struct {
fx.In
*Params
probefx.Probe
routerfx.Router
}
// New create an [App] with [Option]
func New(opts Options) App {
a := &app{
Params: opts.Params,
probe: opts.Probe,
router: opts.Router,
}
a.hProm = promhttp.Handler()
return a
}