21
21
package cadence
22
22
23
23
import (
24
+ "context"
24
25
"fmt"
25
- "log"
26
+ stdLog "log"
26
27
"os"
27
- "os/signal"
28
28
"path/filepath"
29
29
"strings"
30
- "syscall"
31
30
32
31
"github.com/urfave/cli/v2"
32
+ "go.uber.org/fx"
33
33
34
- "github.com/uber/cadence/common"
35
34
"github.com/uber/cadence/common/client"
36
35
"github.com/uber/cadence/common/config"
37
- "github.com/uber/cadence/common/persistence/nosql/nosqlplugin/cassandra/gocql "
36
+ "github.com/uber/cadence/common/log/logfx "
38
37
"github.com/uber/cadence/common/service"
39
- "github.com/uber/cadence/tools/cassandra"
40
- "github.com/uber/cadence/tools/sql"
41
38
)
42
39
43
40
// validServices is the list of all valid cadence services
44
41
var validServices = service .ShortNames (service .List )
45
42
46
- // startHandler is the handler for the cli start command
47
- func startHandler (c * cli.Context ) error {
48
- env := getEnvironment (c )
49
- zone := getZone (c )
50
- configDir := getConfigDir (c )
51
- rootDir := getRootDir (c )
52
-
53
- log .Printf ("Loading config; env=%v,zone=%v,configDir=%v\n " , env , zone , configDir )
54
-
55
- var cfg config.Config
56
- err := config .Load (env , configDir , zone , & cfg )
57
- if err != nil {
58
- return fmt .Errorf ("Config file corrupted: %w" , err )
59
- }
60
- if cfg .Log .Level == "debug" {
61
- log .Printf ("config=%v" , cfg .String ())
62
- }
63
- if cfg .DynamicConfig .Client == "" {
64
- cfg .DynamicConfigClient .Filepath = constructPathIfNeed (rootDir , cfg .DynamicConfigClient .Filepath )
65
- } else {
66
- cfg .DynamicConfig .FileBased .Filepath = constructPathIfNeed (rootDir , cfg .DynamicConfig .FileBased .Filepath )
67
- }
68
-
69
- if err := cfg .ValidateAndFillDefaults (); err != nil {
70
- return fmt .Errorf ("config validation failed: %w" , err )
71
- }
72
- // cassandra schema version validation
73
- if err := cassandra .VerifyCompatibleVersion (cfg .Persistence , gocql .Quorum ); err != nil {
74
- return fmt .Errorf ("cassandra schema version compatibility check failed: %w" , err )
75
- }
76
- // sql schema version validation
77
- if err := sql .VerifyCompatibleVersion (cfg .Persistence ); err != nil {
78
- return fmt .Errorf ("sql schema version compatibility check failed: %w" , err )
79
- }
80
-
81
- var daemons []common.Daemon
82
- services := getServices (c )
83
- sigc := make (chan os.Signal , 1 )
84
- signal .Notify (sigc , syscall .SIGTERM , syscall .SIGINT )
85
- for _ , svc := range services {
86
- server := newServer (svc , & cfg )
87
- daemons = append (daemons , server )
88
- server .Start ()
89
- }
90
-
91
- <- sigc
92
- log .Println ("Received SIGTERM signal, initiating shutdown." )
93
- for _ , daemon := range daemons {
94
- daemon .Stop ()
95
- }
96
- return nil
97
- }
98
-
99
- func getEnvironment (c * cli.Context ) string {
100
- return strings .TrimSpace (c .String ("env" ))
101
- }
102
-
103
- func getZone (c * cli.Context ) string {
104
- return strings .TrimSpace (c .String ("zone" ))
105
- }
106
-
107
- // getServices parses the services arg from cli
108
- // and returns a list of services to start
109
- func getServices (c * cli.Context ) []string {
110
-
111
- val := strings .TrimSpace (c .String ("services" ))
112
- tokens := strings .Split (val , "," )
113
-
114
- if len (tokens ) == 0 {
115
- log .Fatal ("list of services is empty" )
116
- }
117
-
118
- for _ , t := range tokens {
119
- if ! isValidService (t ) {
120
- log .Fatalf ("invalid service `%v` in service list [%v]" , t , val )
121
- }
122
- }
123
-
124
- return tokens
125
- }
126
-
127
43
func isValidService (in string ) bool {
128
44
for _ , s := range validServices {
129
45
if s == in {
@@ -133,31 +49,6 @@ func isValidService(in string) bool {
133
49
return false
134
50
}
135
51
136
- func getConfigDir (c * cli.Context ) string {
137
- return constructPathIfNeed (getRootDir (c ), c .String ("config" ))
138
- }
139
-
140
- func getRootDir (c * cli.Context ) string {
141
- dirpath := c .String ("root" )
142
- if len (dirpath ) == 0 {
143
- cwd , err := os .Getwd ()
144
- if err != nil {
145
- log .Fatalf ("os.Getwd() failed, err=%v" , err )
146
- }
147
- return cwd
148
- }
149
- return dirpath
150
- }
151
-
152
- // constructPathIfNeed would append the dir as the root dir
153
- // when the file wasn't absolute path.
154
- func constructPathIfNeed (dir string , file string ) string {
155
- if ! filepath .IsAbs (file ) {
156
- return dir + "/" + file
157
- }
158
- return file
159
- }
160
-
161
52
// BuildCLI is the main entry point for the cadence server
162
53
func BuildCLI (releaseVersion string , gitRevision string ) * cli.App {
163
54
version := fmt .Sprintf (" Release version: %v \n " +
@@ -217,11 +108,98 @@ func BuildCLI(releaseVersion string, gitRevision string) *cli.App {
217
108
},
218
109
},
219
110
Action : func (c * cli.Context ) error {
220
- return startHandler (c )
111
+ fxApp := fx .New (
112
+ config .Module ,
113
+ logfx .Module ,
114
+ fx .Provide (func () appContext {
115
+ return appContext {
116
+ CfgContext : config.Context {
117
+ Environment : getEnvironment (c ),
118
+ Zone : getZone (c ),
119
+ },
120
+ ConfigDir : getConfigDir (c ),
121
+ RootDir : getRootDir (c ),
122
+ Services : getServices (c ),
123
+ }
124
+ }),
125
+ Module ,
126
+ )
127
+
128
+ ctx := context .Background ()
129
+ if err := fxApp .Start (ctx ); err != nil {
130
+ return err
131
+ }
132
+
133
+ // Block until FX receives a shutdown signal
134
+ <- fxApp .Done ()
135
+
136
+ // Stop the application
137
+ return fxApp .Stop (ctx )
221
138
},
222
139
},
223
140
}
224
141
225
142
return app
226
143
227
144
}
145
+
146
+ type appContext struct {
147
+ fx.Out
148
+
149
+ CfgContext config.Context
150
+ ConfigDir string `name:"config-dir"`
151
+ RootDir string `name:"root-dir"`
152
+ Services []string `name:"services"`
153
+ }
154
+
155
+ func getEnvironment (c * cli.Context ) string {
156
+ return strings .TrimSpace (c .String ("env" ))
157
+ }
158
+
159
+ func getZone (c * cli.Context ) string {
160
+ return strings .TrimSpace (c .String ("zone" ))
161
+ }
162
+
163
+ // getServices parses the services arg from cli
164
+ // and returns a list of services to start
165
+ func getServices (c * cli.Context ) []string {
166
+ val := strings .TrimSpace (c .String ("services" ))
167
+ tokens := strings .Split (val , "," )
168
+
169
+ if len (tokens ) == 0 {
170
+ stdLog .Fatal ("list of services is empty" )
171
+ }
172
+
173
+ for _ , t := range tokens {
174
+ if ! isValidService (t ) {
175
+ stdLog .Fatalf ("invalid service `%v` in service list [%v]" , t , val )
176
+ }
177
+ }
178
+
179
+ return tokens
180
+ }
181
+
182
+ func getConfigDir (c * cli.Context ) string {
183
+ return constructPathIfNeed (getRootDir (c ), c .String ("config" ))
184
+ }
185
+
186
+ func getRootDir (c * cli.Context ) string {
187
+ dirpath := c .String ("root" )
188
+ if len (dirpath ) == 0 {
189
+ cwd , err := os .Getwd ()
190
+ if err != nil {
191
+ stdLog .Fatalf ("os.Getwd() failed, err=%v" , err )
192
+ }
193
+ return cwd
194
+ }
195
+ return dirpath
196
+ }
197
+
198
+ // constructPathIfNeed would append the dir as the root dir
199
+ // when the file wasn't absolute path.
200
+ func constructPathIfNeed (dir string , file string ) string {
201
+ if ! filepath .IsAbs (file ) {
202
+ return dir + "/" + file
203
+ }
204
+ return file
205
+ }
0 commit comments