-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.go
104 lines (82 loc) · 2.22 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
104
package apikit
import (
"context"
"os"
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
"github.com/ziflex/lecho/v3"
"github.com/txsvc/apikit/config"
)
const (
// default ports to listen on
PORT_DEFAULT = "8080"
PORT_DEFAULT_TLS = "433"
// ShutdownDelay is the time to wait for all request, go-routines etc complete
ShutdownDelay = 30 // seconds
)
type (
// SetupFunc creates a new, fully configured router
SetupFunc func() *echo.Echo
// ShutdownFunc is called before the app stops
ShutdownFunc func(context.Context, *App) error
// app holds all configs for the listener
App struct {
svc *echo.Echo
shutdown ShutdownFunc
shutdownDelay time.Duration
// other settings
logLevel log.Lvl
root string
}
)
// New creates a new service listener instance and configures it with sensible defaults.
func New(setupFunc SetupFunc, shutdownFunc ShutdownFunc) (*App, error) {
if setupFunc == nil || shutdownFunc == nil {
return nil, config.ErrInvalidConfiguration
}
app := &App{
svc: setupFunc(),
shutdown: shutdownFunc,
logLevel: log.INFO,
shutdownDelay: ShutdownDelay * time.Second,
}
if app.svc == nil {
return nil, config.ErrInvalidConfiguration
}
// no greetings
app.svc.HideBanner = true
// add a logger and middleware
logger := lecho.New(os.Stdout)
app.svc.Logger = logger
app.svc.Logger.SetLevel(app.logLevel)
// adding logging related middleware
app.svc.Use(middleware.RequestID())
app.svc.Use(lecho.Middleware(lecho.Config{
Logger: logger,
}))
// FIXME: add a default error handler
// app.mux.HTTPErrorHandler = ...
// the root dir for the config
dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
app.root = dir
return app, nil
}
func (a *App) Stop() {
// FIXME: this does not work !
ctx, cancel := context.WithTimeout(context.Background(), a.shutdownDelay)
defer cancel()
// FIXME: which one comes first ? framwork or app shutdown ?
// call the implementation specific shoutdown code to clean-up
if err := a.shutdown(ctx, a); err != nil {
a.svc.Logger.Fatal(err)
}
// shutdown of the framework
if err := a.svc.Shutdown(ctx); err != nil {
a.svc.Logger.Fatal(err)
}
}