77 "os"
88 "time"
99
10- log "github.com/golang/glog"
1110 "google.golang.org/protobuf/encoding/prototext"
1211
1312 "github.com/google/fleetspeak/fleetspeak/src/client"
@@ -20,6 +19,7 @@ import (
2019 "github.com/google/fleetspeak/fleetspeak/src/client/socketservice"
2120 "github.com/google/fleetspeak/fleetspeak/src/client/stats"
2221 "github.com/google/fleetspeak/fleetspeak/src/client/stdinservice"
22+ "github.com/google/fleetspeak/fleetspeak/src/common/fscontext"
2323
2424 gpb "github.com/google/fleetspeak/fleetspeak/src/client/generic/proto/fleetspeak_client_generic"
2525)
@@ -29,42 +29,34 @@ const stopTimeout = time.Minute
2929var configFile = flag .String ("config" , "" , "Client configuration file, required." )
3030
3131func innerMain (ctx context.Context , cfgReloadSignals <- chan os.Signal ) error {
32- for {
33- cl , err := createClient ()
32+ for ctx .Err () == nil {
33+ ctx , cancel := entry .ContextWithSignals (ctx , cfgReloadSignals )
34+ err := runClient (ctx )
35+ cancel ()
3436 if err != nil {
35- return fmt .Errorf ("error starting client: %v" , err )
36- }
37-
38- select {
39- case <- cfgReloadSignals :
40- // We implement config reloading by tearing down the client and creating a
41- // new one.
42- log .Info ("Config reload requested" )
43- time .AfterFunc (stopTimeout , func () {
44- entry .ExitUngracefully (fmt .Errorf ("client did not stop within %s" , stopTimeout ))
45- })
46- cl .Stop ()
47- continue
48- case <- ctx .Done ():
49- // A timeout for process termination is handled higher up.
50- cl .Stop ()
51- return nil
37+ return err
5238 }
5339 }
40+ return nil
5441}
5542
56- func createClient () (* client.Client , error ) {
43+ func runClient (ctx context.Context ) error {
44+ stop := fscontext .AfterDelayFunc (ctx , stopTimeout , func () {
45+ entry .ExitUngracefully (fmt .Errorf ("client did not stop within %s" , stopTimeout ))
46+ })
47+ defer stop ()
48+
5749 b , err := os .ReadFile (* configFile )
5850 if err != nil {
59- return nil , fmt .Errorf ("unable to read configuration file %q: %v" , * configFile , err )
51+ return fmt .Errorf ("unable to read configuration file %q: %v" , * configFile , err )
6052 }
6153 cfgPB := & gpb.Config {}
6254 if err := prototext .Unmarshal (b , cfgPB ); err != nil {
63- return nil , fmt .Errorf ("unable to parse configuration file %q: %v" , * configFile , err )
55+ return fmt .Errorf ("unable to parse configuration file %q: %v" , * configFile , err )
6456 }
6557 cfg , err := generic .MakeConfiguration (cfgPB )
6658 if err != nil {
67- return nil , fmt .Errorf ("error in configuration file: %v" , err )
59+ return fmt .Errorf ("error in configuration file: %v" , err )
6860 }
6961
7062 var com comms.Communicator
@@ -74,7 +66,7 @@ func createClient() (*client.Client, error) {
7466 com = & https.Communicator {}
7567 }
7668
77- return client .New (
69+ cl , err := client .New (
7870 cfg ,
7971 client.Components {
8072 ServiceFactories : map [string ]service.Factory {
@@ -87,6 +79,15 @@ func createClient() (*client.Client, error) {
8779 Stats : stats.NoopCollector {},
8880 },
8981 )
82+ if err != nil {
83+ return fmt .Errorf ("error creating client: %v" , err )
84+ }
85+
86+ select {
87+ case <- ctx .Done ():
88+ cl .Stop ()
89+ }
90+ return nil
9091}
9192
9293func main () {
0 commit comments