-
Notifications
You must be signed in to change notification settings - Fork 217
/
main.go
139 lines (130 loc) · 4.2 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"context"
"errors"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"
"github.com/artifacthub/hub/cmd/hub/handlers"
"github.com/artifacthub/hub/internal/apikey"
"github.com/artifacthub/hub/internal/authz"
"github.com/artifacthub/hub/internal/email"
"github.com/artifacthub/hub/internal/event"
"github.com/artifacthub/hub/internal/hub"
"github.com/artifacthub/hub/internal/img/pg"
"github.com/artifacthub/hub/internal/notification"
"github.com/artifacthub/hub/internal/org"
"github.com/artifacthub/hub/internal/pkg"
"github.com/artifacthub/hub/internal/repo"
"github.com/artifacthub/hub/internal/subscription"
"github.com/artifacthub/hub/internal/user"
"github.com/artifacthub/hub/internal/util"
"github.com/artifacthub/hub/internal/webhook"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/rs/zerolog/log"
)
func main() {
// Setup configuration and logger
cfg, err := util.SetupConfig("hub")
if err != nil {
log.Fatal().Err(err).Msg("configuration setup failed")
}
fields := map[string]interface{}{"cmd": "hub"}
if err := util.SetupLogger(cfg, fields); err != nil {
log.Fatal().Err(err).Msg("logger setup failed")
}
// Setup services
db, err := util.SetupDB(cfg)
if err != nil {
log.Fatal().Err(err).Msg("database setup failed")
}
var es hub.EmailSender
if s := email.NewSender(cfg); s != nil {
es = s
}
az, err := authz.NewAuthorizer(db)
if err != nil {
log.Fatal().Err(err).Msg("authorizer setup failed")
}
hc := &http.Client{Timeout: 10 * time.Second}
// Setup and launch http server
ctx, stop := context.WithCancel(context.Background())
hSvc := &handlers.Services{
OrganizationManager: org.NewManager(db, es, az),
UserManager: user.NewManager(db, es),
RepositoryManager: repo.NewManager(cfg, db, az),
PackageManager: pkg.NewManager(db),
SubscriptionManager: subscription.NewManager(db),
WebhookManager: webhook.NewManager(db),
APIKeyManager: apikey.NewManager(db),
ImageStore: pg.NewImageStore(cfg, db, hc, nil),
Authorizer: az,
}
h, err := handlers.Setup(ctx, cfg, hSvc)
if err != nil {
log.Fatal().Err(err).Msg("handlers setup failed")
}
addr := cfg.GetString("server.addr")
srv := &http.Server{
Addr: addr,
ReadTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 1 * time.Minute,
Handler: h.Router,
}
go func() {
if err := srv.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
log.Fatal().Err(err).Msg("hub server ListenAndServe failed")
}
}()
log.Info().Str("addr", addr).Int("pid", os.Getpid()).Msg("hub server running!")
// Setup and launch metrics server
go func() {
http.Handle("/metrics", promhttp.Handler())
err := http.ListenAndServe(cfg.GetString("server.metricsAddr"), nil)
if err != nil {
log.Fatal().Err(err).Msg("metrics server ListenAndServe failed")
}
}()
// Setup and launch events dispatcher
var wg sync.WaitGroup
eSvc := &event.Services{
DB: db,
EventManager: event.NewManager(),
SubscriptionManager: subscription.NewManager(db),
WebhookManager: webhook.NewManager(db),
NotificationManager: notification.NewManager(),
}
eventsDispatcher := event.NewDispatcher(eSvc)
wg.Add(1)
go eventsDispatcher.Run(ctx, &wg)
// Setup and launch notifications dispatcher
nSvc := ¬ification.Services{
DB: db,
ES: es,
NotificationManager: notification.NewManager(),
SubscriptionManager: subscription.NewManager(db),
RepositoryManager: repo.NewManager(cfg, db, az),
PackageManager: pkg.NewManager(db),
}
notificationsDispatcher := notification.NewDispatcher(cfg, nSvc)
wg.Add(1)
go notificationsDispatcher.Run(ctx, &wg)
// Shutdown server gracefully when SIGINT or SIGTERM signal is received
shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
<-shutdown
log.Info().Msg("hub server shutting down..")
stop()
wg.Wait()
ctx, cancel := context.WithTimeout(context.Background(), cfg.GetDuration("server.shutdownTimeout"))
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Error().Err(err).Msg("hub server shutdown failed")
return
}
log.Info().Msg("hub server stopped")
}