lib/ur: Send unreported failures on shutdown (#7164)

This commit is contained in:
Simon Frei
2020-12-22 20:17:14 +01:00
committed by GitHub
parent 4bcc38cf63
commit a20a5f61f0
21 changed files with 296 additions and 206 deletions
-103
View File
@@ -8,7 +8,6 @@ package util
import (
"context"
"errors"
"fmt"
"net"
"net/url"
@@ -17,9 +16,6 @@ import (
"strings"
"time"
"github.com/syncthing/syncthing/lib/logger"
"github.com/syncthing/syncthing/lib/sync"
"github.com/thejerf/suture/v4"
)
@@ -263,19 +259,6 @@ type FatalErr struct {
Status ExitStatus
}
// AsFatalErr wraps the given error creating a FatalErr. If the given error
// already is of type FatalErr, it is not wrapped again.
func AsFatalErr(err error, status ExitStatus) *FatalErr {
var ferr *FatalErr
if errors.As(err, &ferr) {
return ferr
}
return &FatalErr{
Err: err,
Status: status,
}
}
func (e *FatalErr) Error() string {
return e.Err.Error()
}
@@ -327,61 +310,6 @@ func (s ExitStatus) AsInt() int {
return int(s)
}
type ServiceWithError interface {
suture.Service
fmt.Stringer
Error() error
SetError(error)
}
// AsService wraps the given function to implement suture.Service. In addition
// it keeps track of the returned error and allows querying and setting that error.
func AsService(fn func(ctx context.Context) error, creator string) ServiceWithError {
return &service{
creator: creator,
serve: fn,
mut: sync.NewMutex(),
}
}
type service struct {
creator string
serve func(ctx context.Context) error
err error
mut sync.Mutex
}
func (s *service) Serve(ctx context.Context) error {
s.mut.Lock()
s.err = nil
s.mut.Unlock()
err := s.serve(ctx)
s.mut.Lock()
s.err = err
s.mut.Unlock()
return err
}
func (s *service) Error() error {
s.mut.Lock()
defer s.mut.Unlock()
return s.err
}
func (s *service) SetError(err error) {
s.mut.Lock()
s.err = err
s.mut.Unlock()
}
func (s *service) String() string {
return fmt.Sprintf("Service@%p created by %v", s, s.creator)
}
// OnDone calls fn when ctx is cancelled.
func OnDone(ctx context.Context, fn func()) {
go func() {
@@ -390,37 +318,6 @@ func OnDone(ctx context.Context, fn func()) {
}()
}
type doneService struct {
fn func()
}
func (s *doneService) Serve(ctx context.Context) error {
<-ctx.Done()
s.fn()
return nil
}
// OnSupervisorDone calls fn when sup is done.
func OnSupervisorDone(sup *suture.Supervisor, fn func()) {
sup.Add(&doneService{fn})
}
func SpecWithDebugLogger(l logger.Logger) suture.Spec {
return spec(func(e suture.Event) { l.Debugln(e) })
}
func SpecWithInfoLogger(l logger.Logger) suture.Spec {
return spec(func(e suture.Event) { l.Infoln(e) })
}
func spec(eventHook suture.EventHook) suture.Spec {
return suture.Spec{
EventHook: eventHook,
PassThroughPanics: true,
DontPropagateTermination: false,
}
}
func CallWithContext(ctx context.Context, fn func() error) error {
var err error
done := make(chan struct{})