-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
167 lines (141 loc) · 4.58 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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package main
import (
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"runtime"
"strings"
"syscall"
"time"
logrus "github.com/sirupsen/logrus"
)
// AppPath returns the application path based on the OS.
func AppPath(goos, homeDir string) string {
// Determine the application path based on the operating system.
switch goos {
case "windows":
// On Windows, use the LOCALAPPDATA environment variable.
return filepath.Join(os.Getenv("LOCALAPPDATA"), DefaultAppName)
case "darwin":
// On macOS, place the application data in the
// "Application Support" directory.
return filepath.Join(
homeDir, "Library", "Application Support", DefaultAppName,
)
case "plan9":
// On Plan 9, use the home directory with the application name
// in lowercase.
return filepath.Join(homeDir, strings.ToLower(DefaultAppName))
// POSIX (Linux, etc.)
default:
// On other POSIX systems (e.g., Linux), use a hidden directory
// in the home directory.
appName := fmt.Sprintf(".%s", strings.ToLower(DefaultAppName))
return filepath.Join(homeDir, appName)
}
}
// EnsureAppPathExists ensures the application directory exists.
func EnsureAppPathExists(path string) error {
if _, err := os.Stat(path); os.IsNotExist(err) {
err := os.MkdirAll(path, AppDirPermissions)
if err != nil {
return err
}
}
return nil
}
func main() {
// Get the user home directory depending on the OS.
homeDir, err := os.UserHomeDir()
if err != nil {
logrus.Fatalf("Failed to get user home directory: %v", err)
}
// Get the app path directory.
appPath := AppPath(runtime.GOOS, homeDir)
// Create App Path if it doesn't exist.
err = EnsureAppPathExists(appPath)
if err != nil {
logrus.Fatalf("Failed to create app directory: %v",
err)
}
// Initiate Config.
config, err := initConfig(appPath, DefaultConfigFilename)
if err != nil {
logrus.Fatalf("Failed to initialize configuration: %v", err)
}
// Setup logging.
err = setupLogging(config)
if err != nil {
logrus.Fatalf("Failed to set up logging : %v", err)
}
logrus.Info("Logging setup complete")
// Setup the database.
db, err := setupDatabase(config)
if err != nil {
logrus.Fatalf("Failed to set up database: %v", err)
}
defer cleanupDB(db)
logrus.Info("Database setup complete")
// Create Third Party TLS Path if it doesn't exit.
if err := CreateThirdPartyTLSDirIfNotExist(config); err != nil {
logrus.Fatalf("Failed to create third party TLS dir: %v ", err)
}
// Load TLS Configurations.
tlsCreds, err := loadTLSCredentials(config)
if err != nil {
logrus.Fatalf("Failed to load TLS credentials: %v", err)
}
logrus.Info("TLS configurations loaded")
// Create the external coordinator server.
server := NewExternalCoordinatorServer(config, db)
// Create a ticker that ticks every interval specified in the server
// configuration.
staleDataCleanupTicker := time.NewTicker(
server.config.Server.StaleDataCleanupInterval,
)
defer staleDataCleanupTicker.Stop()
// Create a cancellable context for the cleanup routine.
cleanupCtx, cleanupCancel := context.WithCancel(context.Background())
defer cleanupCancel()
// Run the cleanup routine.
server.RunCleanupRoutine(cleanupCtx, staleDataCleanupTicker)
// Initialize and start the pprof server.
pprofServer := initializePProfServer(config, tlsCreds)
go func() {
if err := startPProfServer(config, pprofServer); err != nil {
logrus.Fatalf("Failed to start pprof server: %v", err)
}
}()
// Initialize and start the gRPC server.
grpcServer, lis, err := initializeGRPCServer(config, tlsCreds, server)
if err != nil {
logrus.Fatalf("Failed to initialize gRPC server: %v", err)
}
go func() {
if err := startGRPCServer(config, grpcServer, lis); err != nil {
logrus.Fatalf("Failed to start gRPC server: %v", err)
}
}()
// Create a cancellable context for the gRPC REST gateway.
restCtx, restCancel := context.WithCancel(context.Background())
defer restCancel()
// Initialize and start the HTTP server for the gRPC REST gateway.
httpServer, err := initializeHTTPServer(restCtx, tlsCreds, config)
if err != nil {
logrus.Fatalf("Failed to initialize HTTP server: %v", err)
}
go func() {
if err := startHTTPServer(config, httpServer); err != nil {
logrus.Fatalf("Failed to start HTTP server: %v", err)
}
}()
// Create a channel to listen for interrupt or termination signals from
// the OS.
sigChan := make(chan os.Signal, 1)
// Notify sigChan on os.Interrupt or syscall.SIGTERM.
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
// Handle graceful shutdown for the gRPC, HTTP, and pprof servers.
gracefulShutdown(sigChan, grpcServer, httpServer, pprofServer)
}