-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
111 lines (90 loc) · 2.89 KB
/
main.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
105
106
107
108
109
110
111
package main
import (
"context"
"embed"
"fmt"
"io/fs"
"net/http"
"net/url"
"os"
"os/signal"
"syscall"
"time"
"github.com/adrg/xdg"
"github.com/envelope-zero/backend/v4/pkg/models"
"github.com/envelope-zero/backend/v4/pkg/router"
"github.com/gin-contrib/static"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/skratchdot/open-golang/open"
)
// Embedding code taken from https://github.com/gin-contrib/static/issues/19#issue-830589998
//
// Embed the "public" directory as filesystem
//
//go:embed public
var server embed.FS
type embedFileSystem struct {
http.FileSystem
}
func (e embedFileSystem) Exists(_, path string) bool {
_, err := e.Open(path)
return err == nil
}
func EmbedFolder(fsEmbed embed.FS, targetPath string) static.ServeFileSystem {
fsys, err := fs.Sub(fsEmbed, targetPath)
if err != nil {
log.Fatal().Msg(err.Error())
}
return embedFileSystem{
FileSystem: http.FS(fsys),
}
}
func main() {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
dbPath, err := xdg.DataFile("envelope-zero/envelope-zero.db")
if err != nil {
log.Fatal().Msg(err.Error())
}
log.Info().Str("database file", dbPath).Msg("Init")
dbConnectionOptions := "_pragma=foreign_keys(1)"
err = models.Connect(fmt.Sprintf("%s?%s", dbPath, dbConnectionOptions))
if err != nil {
log.Fatal().Msg(err.Error())
}
url, _ := url.Parse("http://localhost:3200/api")
r, teardown, err := router.Config(url)
if err != nil {
log.Fatal().Msg(err.Error())
}
defer teardown()
// Attach all backend routes to /api
router.AttachRoutes(r.Group("/api/"))
// Serve the frontend on /
r.Use(static.Serve("/", EmbedFolder(server, "public")))
// The following code is taken from https://github.com/gin-gonic/examples/blob/91fb0d925b3935d2c6e4d9336d78cf828925789d/graceful-shutdown/graceful-shutdown/notify-without-context/server.go
// and has been modified to not wait for the timeout to expire before returning
srv := &http.Server{
Addr: ":3200",
Handler: r,
}
_ = open.Run("http://localhost:3200")
// Wait for interrupt signal to gracefully shutdown the server with a timeout of 5 seconds.
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal().Str("event", "Error during startup").Err(err).Msg("Router")
}
}()
log.Info().Str("event", "Startup complete").Msg("Router")
<-quit
log.Info().Str("event", "Received SIGINT or SIGTERM, stopping gracefully with 25 seconds timeout").Msg("Router")
// Create a context with a 25 second timeout for the server to shut down in
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal().Str("event", "Graceful shutdown failed, terminating").Err(err).Msg("Router")
}
log.Info().Str("event", "Backend stopped").Msg("Router")
}