Cleanup exit handling

This commit is contained in:
andig 2022-10-15 13:33:41 +02:00
parent 5026dd0a68
commit 7ee3f95467
2 changed files with 29 additions and 38 deletions

View file

@ -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)
}

View file

@ -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())
}