lib/db: Make database GC a service, stop on Stop() (#6518)
This makes the GC runner a service that will stop fairly quickly when told to. As a bonus, STTRACE=app will print the service tree on the way out, including any errors they've flagged.
This commit is contained in:
@@ -13,3 +13,7 @@ import (
|
||||
var (
|
||||
l = logger.DefaultLogger.NewFacility("app", "Main run facility")
|
||||
)
|
||||
|
||||
func shouldDebug() bool {
|
||||
return l.ShouldDebug("app")
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -126,6 +128,7 @@ func (a *App) startup() error {
|
||||
},
|
||||
PassThroughPanics: true,
|
||||
})
|
||||
a.mainService.Add(a.ll)
|
||||
a.mainService.ServeBackground()
|
||||
|
||||
if a.opts.AuditWriter != nil {
|
||||
@@ -371,6 +374,10 @@ func (a *App) startup() error {
|
||||
func (a *App) run() {
|
||||
<-a.stop
|
||||
|
||||
if shouldDebug() {
|
||||
l.Debugln("Services before stop:")
|
||||
printServiceTree(os.Stdout, a.mainService, 0)
|
||||
}
|
||||
a.mainService.Stop()
|
||||
|
||||
done := make(chan struct{})
|
||||
@@ -475,3 +482,37 @@ func (e *controller) Shutdown() {
|
||||
func (e *controller) ExitUpgrading() {
|
||||
e.Stop(ExitUpgrade)
|
||||
}
|
||||
|
||||
type supervisor interface{ Services() []suture.Service }
|
||||
|
||||
func printServiceTree(w io.Writer, sup supervisor, level int) {
|
||||
printService(w, sup, level)
|
||||
|
||||
svcs := sup.Services()
|
||||
sort.Slice(svcs, func(a, b int) bool {
|
||||
return fmt.Sprint(svcs[a]) < fmt.Sprint(svcs[b])
|
||||
})
|
||||
|
||||
for _, svc := range svcs {
|
||||
if sub, ok := svc.(supervisor); ok {
|
||||
printServiceTree(w, sub, level+1)
|
||||
} else {
|
||||
printService(w, svc, level+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printService(w io.Writer, svc interface{}, level int) {
|
||||
type errorer interface{ Error() error }
|
||||
|
||||
t := "-"
|
||||
if _, ok := svc.(supervisor); ok {
|
||||
t = "+"
|
||||
}
|
||||
fmt.Fprintln(w, strings.Repeat(" ", level), t, svc)
|
||||
if es, ok := svc.(errorer); ok {
|
||||
if err := es.Error(); err != nil {
|
||||
fmt.Fprintln(w, strings.Repeat(" ", level), " ->", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user