Cleanup exit handling
This commit is contained in:
parent
5026dd0a68
commit
7ee3f95467
2 changed files with 29 additions and 38 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
40
cmd/root.go
40
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())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue