diff --git a/cmd/helper.go b/cmd/helper.go index a6b736459..863475ab8 100644 --- a/cmd/helper.go +++ b/cmd/helper.go @@ -8,7 +8,6 @@ import ( "regexp" "strconv" "strings" - "time" "github.com/evcc-io/evcc/cmd/shutdown" "github.com/evcc-io/evcc/util" @@ -62,29 +61,29 @@ func redact(src string) string { ReplaceAllString(src, "$1: *****") } -func publishErrorInfo(cfgFile string, err error) { +func publishErrorInfo(valueChan chan<- util.Param, cfgFile string, err error) { if cfgFile != "" { file, pathErr := filepath.Abs(cfgFile) if pathErr != nil { file = cfgFile } - publish("file", file) + valueChan <- util.Param{Key: "file", Val: file} if src, fileErr := os.ReadFile(cfgFile); fileErr != nil { log.ERROR.Println("could not open config file:", fileErr) } else { - publish("config", redact(string(src))) + valueChan <- util.Param{Key: "config", Val: redact(string(src))} // find line number if match := regexp.MustCompile(`yaml: line (\d+):`).FindStringSubmatch(err.Error()); len(match) == 2 { if line, err := strconv.Atoi(match[1]); err == nil { - publish("line", line) + valueChan <- util.Param{Key: "line", Val: line} } } } } - publish("fatal", unwrap(err)) + valueChan <- util.Param{Key: "fatal", Val: unwrap(err)} } // fatal logs a fatal error and runs shutdown functions before terminating @@ -100,19 +99,3 @@ func shutdownDoneC() <-chan struct{} { go shutdown.Cleanup(doneC) return doneC } - -// exitWhenDone waits for shutdown to complete with timeout -func exitWhenDone(timeout time.Duration) { - select { - case <-shutdownDoneC(): // wait for shutdown - case <-time.After(timeout): - } - - os.Exit(1) -} - -// exitWhenStopped waits for stop and performs shutdown -func exitWhenStopped(stopC <-chan struct{}, timeout time.Duration) { - <-stopC - exitWhenDone(timeout) -} diff --git a/cmd/root.go b/cmd/root.go index bcacfe0ea..56e7763d4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -25,6 +25,8 @@ import ( "github.com/spf13/viper" ) +const rebootDelay = 5 * time.Minute // delayed reboot on error + var ( log = util.NewLogger("main") cfgFile string @@ -95,12 +97,6 @@ func Execute() { } } -var valueChan chan util.Param - -func publish(key string, val any) { - valueChan <- util.Param{Key: key, Val: val} -} - func runRoot(cmd *cobra.Command, args []string) { // load config and re-configure logging after reading config file var err error @@ -143,7 +139,7 @@ func runRoot(cmd *cobra.Command, args []string) { go socketHub.Run(tee.Attach(), cache) // setup values channel - valueChan = make(chan util.Param) + valueChan := make(chan util.Param) go tee.Run(valueChan) // setup environment @@ -214,7 +210,7 @@ func runRoot(cmd *cobra.Command, args []string) { // expose sponsor to UI if sponsor.Subject != "" { - publish("sponsor", sponsor.Subject) + valueChan <- util.Param{Key: "sponsor", Val: sponsor.Subject} } // allow web access for vehicles @@ -231,23 +227,35 @@ func runRoot(cmd *cobra.Command, args []string) { }) }) - // delayed reboot on error - const rebootDelay = 5 * time.Minute - log.FATAL.Println(err) log.FATAL.Printf("will attempt restart in: %v", rebootDelay) - publishErrorInfo(cfgFile, err) - - // wait for shutdown - go exitWhenStopped(stopC, rebootDelay) + publishErrorInfo(valueChan, cfgFile, err) } // uds health check listener go server.HealthListener(site) // wait for shutdown - go exitWhenStopped(stopC, conf.Interval) + go func() { + <-stopC + + timeout := conf.Interval + if err != nil { + timeout = rebootDelay + } + + select { + case <-shutdownDoneC(): // wait for shutdown + case <-time.After(timeout): + } + + if err != nil { + os.Exit(1) + } + + os.Exit(0) + }() log.FATAL.Println(httpd.ListenAndServe()) }