/
main.go
153 lines (127 loc) · 4.44 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"context"
"flag"
"os"
"time"
"code.cloudfoundry.org/bbs/db/sqldb/helpers"
"code.cloudfoundry.org/bbs/db/sqldb/helpers/monitor"
"code.cloudfoundry.org/bbs/guidprovider"
"code.cloudfoundry.org/clock"
"code.cloudfoundry.org/debugserver"
loggingclient "code.cloudfoundry.org/diego-logging-client"
"code.cloudfoundry.org/go-loggregator/v8/runtimeemitter"
"code.cloudfoundry.org/lager/v3"
"code.cloudfoundry.org/lager/v3/lagerflags"
"code.cloudfoundry.org/locket"
"code.cloudfoundry.org/locket/cmd/locket/config"
"code.cloudfoundry.org/locket/db"
"code.cloudfoundry.org/locket/expiration"
"code.cloudfoundry.org/locket/grpcserver"
"code.cloudfoundry.org/locket/handlers"
"code.cloudfoundry.org/locket/metrics"
metrics_helpers "code.cloudfoundry.org/locket/metrics/helpers"
"code.cloudfoundry.org/tlsconfig"
"github.com/tedsuo/ifrit"
"github.com/tedsuo/ifrit/grouper"
"github.com/tedsuo/ifrit/sigmon"
)
var configFilePath = flag.String(
"config",
"",
"Path to Locket JSON Configuration file",
)
func main() {
flag.Parse()
cfg, err := config.NewLocketConfig(*configFilePath)
if err != nil {
panic("invalid-config-file: " + err.Error())
}
logger, reconfigurableSink := lagerflags.NewFromConfig("locket", cfg.LagerConfig)
metronClient, err := initializeMetron(logger, cfg)
if err != nil {
logger.Error("failed-to-initialize-metron-client", err)
os.Exit(1)
}
clock := clock.NewClock()
sqlConn, err := helpers.Connect(
logger,
cfg.DatabaseDriver,
cfg.DatabaseConnectionString,
cfg.SQLCACertFile,
cfg.SQLEnableIdentityVerification,
)
if err != nil {
logger.Fatal("failed-to-open-sql", err)
}
defer sqlConn.Close()
sqlConn.SetMaxIdleConns(cfg.MaxOpenDatabaseConnections)
sqlConn.SetMaxOpenConns(cfg.MaxOpenDatabaseConnections)
sqlConn.SetConnMaxLifetime(time.Duration(cfg.MaxDatabaseConnectionLifetime))
err = sqlConn.Ping()
if err != nil {
logger.Fatal("sql-failed-to-connect", err)
}
dbMonitor := monitor.New()
monitoredDB := helpers.NewMonitoredDB(sqlConn, dbMonitor)
sqlDB := db.NewSQLDB(
monitoredDB,
cfg.DatabaseDriver,
guidprovider.DefaultGuidProvider,
)
err = sqlDB.CreateLockTable(context.Background(), logger)
if err != nil {
logger.Fatal("failed-to-create-lock-table", err)
}
tlsConfig, err := tlsconfig.Build(
tlsconfig.WithInternalServiceDefaults(),
tlsconfig.WithIdentityFromFile(cfg.CertFile, cfg.KeyFile),
).Server(tlsconfig.WithClientAuthenticationFromFile(cfg.CaFile))
if err != nil {
logger.Fatal("invalid-tls-config", err)
}
lockMetricsNotifier := metrics.NewLockMetricsNotifier(logger, clock, metronClient, time.Duration(cfg.ReportInterval), sqlDB)
dbMetricsNotifier := metrics.NewDBMetricsNotifier(logger, clock, metronClient, time.Duration(cfg.ReportInterval), sqlDB, dbMonitor)
requestNotifier := metrics_helpers.NewRequestMetricsNotifier(logger, clock, metronClient, time.Duration(cfg.ReportInterval), []string{"Lock", "Release", "Fetch", "FetchAll"})
lockPick := expiration.NewLockPick(sqlDB, clock, metronClient)
burglar := expiration.NewBurglar(logger, sqlDB, lockPick, clock, locket.RetryInterval, metronClient)
exitCh := make(chan struct{})
handler := handlers.NewLocketHandler(logger, sqlDB, lockPick, requestNotifier, exitCh)
server := grpcserver.NewGRPCServer(logger, cfg.ListenAddress, tlsConfig, handler)
members := grouper.Members{
{Name: "server", Runner: server},
{Name: "burglar", Runner: burglar},
{Name: "lock-metrics-notifier", Runner: lockMetricsNotifier},
{Name: "db-metrics-notifier", Runner: dbMetricsNotifier},
{Name: "request-metrics-notifier", Runner: requestNotifier},
}
if cfg.DebugAddress != "" {
members = append(grouper.Members{
{Name: "debug-server", Runner: debugserver.Runner(cfg.DebugAddress, reconfigurableSink)},
}, members...)
}
group := grouper.NewOrdered(os.Interrupt, members)
monitor := ifrit.Invoke(sigmon.New(group))
logger.Info("started")
go func() {
<-exitCh
logger.Info("shutting-down-due-to-unrecoverable-error")
monitor.Signal(os.Interrupt)
}()
err = <-monitor.Wait()
if err != nil {
logger.Error("exited-with-failure", err)
os.Exit(1)
}
}
func initializeMetron(logger lager.Logger, locketConfig config.LocketConfig) (loggingclient.IngressClient, error) {
client, err := loggingclient.NewIngressClient(locketConfig.LoggregatorConfig)
if err != nil {
return nil, err
}
if locketConfig.LoggregatorConfig.UseV2API {
emitter := runtimeemitter.NewV1(client)
go emitter.Run()
}
return client, nil
}