-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathmain.go
More file actions
136 lines (121 loc) · 3.31 KB
/
main.go
File metadata and controls
136 lines (121 loc) · 3.31 KB
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
package main
import (
"context"
"fmt"
"os"
"os/signal"
"runtime/debug"
"syscall"
"github.com/cybertec-postgresql/pg_timetable/internal/api"
"github.com/cybertec-postgresql/pg_timetable/internal/config"
"github.com/cybertec-postgresql/pg_timetable/internal/log"
"github.com/cybertec-postgresql/pg_timetable/internal/pgengine"
"github.com/cybertec-postgresql/pg_timetable/internal/scheduler"
)
/**
* pg_timetable is the daemon application responsible to execute scheduled SQL tasks that cannot be triggered by the
* PostgreSQL server (PostgreSQL does not support time triggers).
*
* This application may run on the same machine as PostgreSQL server and must grant full access permission to the
* timetable tables.
*/
var pge *pgengine.PgEngine
// SetupCloseHandler creates a 'listener' on a new goroutine which will notify the
// program if it receives an interrupt from the OS. We then handle this by calling
// our clean up procedure and exiting the program.
func SetupCloseHandler(cancel context.CancelFunc) {
c := make(chan os.Signal, 2)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
cancel()
exitCode = ExitCodeUserCancel
}()
}
const (
ExitCodeOK int = iota
ExitCodeConfigError
ExitCodeDBEngineError
ExitCodeUpgradeError
ExitCodeUserCancel
ExitCodeShutdownCommand
ExitCodeFatalError
)
var exitCode = ExitCodeOK
// version output variables
var (
commit = "000000"
version = "master"
date = "unknown"
dbapi = "00733"
)
func printVersion() {
fmt.Printf(`pg_timetable:
Version: %s
DB Schema: %s
Git Commit: %s
Built: %s
`, version, dbapi, commit, date)
}
// run contains the core application logic and returns an exit code.
func run(ctx context.Context, cmdOpts *config.CmdOptions, logger log.LoggerHookerIface) int {
apiserver := api.Init(cmdOpts.RESTApi, logger)
var err error
if pge, err = pgengine.New(ctx, *cmdOpts, logger); err != nil {
logger.WithError(err).Error("Connection failed")
return ExitCodeDBEngineError
}
defer pge.Finalize()
if cmdOpts.Start.Upgrade {
if err := pge.MigrateDb(ctx); err != nil {
logger.WithError(err).Error("Upgrade failed")
return ExitCodeUpgradeError
}
} else {
if upgrade, err := pge.CheckNeedMigrateDb(ctx); upgrade || err != nil {
if upgrade {
logger.Error("You need to upgrade your database before proceeding, use --upgrade option")
}
if err != nil {
logger.WithError(err).Error("Migration check failed")
}
return ExitCodeUpgradeError
}
}
if cmdOpts.Start.Init {
return ExitCodeOK
}
sch := scheduler.New(pge, logger)
apiserver.APIHandler = sch
if sch.Run(ctx) == scheduler.ShutdownStatus {
return ExitCodeShutdownCommand
}
return ExitCodeOK
}
func main() {
cmdOpts, err := config.NewConfig(os.Stdout)
if err != nil {
if cmdOpts != nil && cmdOpts.VersionOnly() {
printVersion()
return
}
fmt.Println("Configuration error: ", err)
exitCode = ExitCodeConfigError
return
}
if cmdOpts.Version {
printVersion()
}
logger := log.Init(cmdOpts.Logging)
ctx, cancel := context.WithCancel(context.Background())
SetupCloseHandler(cancel)
defer func() {
cancel()
if err := recover(); err != nil {
exitCode = ExitCodeFatalError
logger.WithField("callstack", string(debug.Stack())).Error(err)
}
os.Exit(exitCode)
}()
exitCode = run(ctx, cmdOpts, logger)
}