mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-02 22:50:18 +00:00
lib/ur: Send unreported failures on shutdown (#7164)
This commit is contained in:
parent
4bcc38cf63
commit
a20a5f61f0
@ -39,10 +39,10 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/logger"
|
"github.com/syncthing/syncthing/lib/logger"
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/syncthing"
|
"github.com/syncthing/syncthing/lib/syncthing"
|
||||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||||
"github.com/syncthing/syncthing/lib/upgrade"
|
"github.com/syncthing/syncthing/lib/upgrade"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -323,7 +323,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Command line options:", err)
|
l.Warnln("Command line options:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.logFile == "default" || options.logFile == "" {
|
if options.logFile == "default" || options.logFile == "" {
|
||||||
@ -360,7 +360,7 @@ func main() {
|
|||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Error reading device ID:", err)
|
l.Warnln("Error reading device ID:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(protocol.NewDeviceID(cert.Certificate[0]))
|
fmt.Println(protocol.NewDeviceID(cert.Certificate[0]))
|
||||||
@ -370,7 +370,7 @@ func main() {
|
|||||||
if options.browserOnly {
|
if options.browserOnly {
|
||||||
if err := openGUI(protocol.EmptyDeviceID); err != nil {
|
if err := openGUI(protocol.EmptyDeviceID); err != nil {
|
||||||
l.Warnln("Failed to open web UI:", err)
|
l.Warnln("Failed to open web UI:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ func main() {
|
|||||||
if options.generateDir != "" {
|
if options.generateDir != "" {
|
||||||
if err := generate(options.generateDir); err != nil {
|
if err := generate(options.generateDir); err != nil {
|
||||||
l.Warnln("Failed to generate config and keys:", err)
|
l.Warnln("Failed to generate config and keys:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -386,14 +386,14 @@ func main() {
|
|||||||
// Ensure that our home directory exists.
|
// Ensure that our home directory exists.
|
||||||
if err := ensureDir(locations.GetBaseDir(locations.ConfigBaseDir), 0700); err != nil {
|
if err := ensureDir(locations.GetBaseDir(locations.ConfigBaseDir), 0700); err != nil {
|
||||||
l.Warnln("Failure on home directory:", err)
|
l.Warnln("Failure on home directory:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.upgradeTo != "" {
|
if options.upgradeTo != "" {
|
||||||
err := upgrade.ToURL(options.upgradeTo)
|
err := upgrade.ToURL(options.upgradeTo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Error while Upgrading:", err)
|
l.Warnln("Error while Upgrading:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
l.Infoln("Upgraded from", options.upgradeTo)
|
l.Infoln("Upgraded from", options.upgradeTo)
|
||||||
return
|
return
|
||||||
@ -424,13 +424,13 @@ func main() {
|
|||||||
os.Exit(exitCodeForUpgrade(err))
|
os.Exit(exitCodeForUpgrade(err))
|
||||||
}
|
}
|
||||||
l.Infof("Upgraded to %q", release.Tag)
|
l.Infof("Upgraded to %q", release.Tag)
|
||||||
os.Exit(util.ExitUpgrade.AsInt())
|
os.Exit(svcutil.ExitUpgrade.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.resetDatabase {
|
if options.resetDatabase {
|
||||||
if err := resetDB(); err != nil {
|
if err := resetDB(); err != nil {
|
||||||
l.Warnln("Resetting database:", err)
|
l.Warnln("Resetting database:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
l.Infoln("Successfully reset database - it will be rebuilt after next start.")
|
l.Infoln("Successfully reset database - it will be rebuilt after next start.")
|
||||||
return
|
return
|
||||||
@ -610,7 +610,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
cfg, err := syncthing.LoadConfigAtStartup(locations.Get(locations.ConfigFile), cert, evLogger, runtimeOptions.allowNewerConfig, noDefaultFolder)
|
cfg, err := syncthing.LoadConfigAtStartup(locations.Get(locations.ConfigFile), cert, evLogger, runtimeOptions.allowNewerConfig, noDefaultFolder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Failed to initialize config:", err)
|
l.Warnln("Failed to initialize config:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Candidate builds should auto upgrade. Make sure the option is set,
|
// Candidate builds should auto upgrade. Make sure the option is set,
|
||||||
@ -656,7 +656,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l.Infof("Upgraded to %q, exiting now.", release.Tag)
|
l.Infof("Upgraded to %q, exiting now.", release.Tag)
|
||||||
os.Exit(util.ExitUpgrade.AsInt())
|
os.Exit(svcutil.ExitUpgrade.AsInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,7 +684,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
app, err := syncthing.New(cfg, ldb, evLogger, cert, appOpts)
|
app, err := syncthing.New(cfg, ldb, evLogger, cert, appOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Failed to start Syncthing:", err)
|
l.Warnln("Failed to start Syncthing:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
if autoUpgradePossible {
|
if autoUpgradePossible {
|
||||||
@ -701,18 +701,18 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
f, err := os.Create(fmt.Sprintf("cpu-%d.pprof", os.Getpid()))
|
f, err := os.Create(fmt.Sprintf("cpu-%d.pprof", os.Getpid()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Creating profile:", err)
|
l.Warnln("Creating profile:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
if err := pprof.StartCPUProfile(f); err != nil {
|
if err := pprof.StartCPUProfile(f); err != nil {
|
||||||
l.Warnln("Starting profile:", err)
|
l.Warnln("Starting profile:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go standbyMonitor(app, cfg)
|
go standbyMonitor(app, cfg)
|
||||||
|
|
||||||
if err := app.Start(); err != nil {
|
if err := app.Start(); err != nil {
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanConfigDirectory()
|
cleanConfigDirectory()
|
||||||
@ -725,7 +725,7 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
|
|||||||
|
|
||||||
status := app.Wait()
|
status := app.Wait()
|
||||||
|
|
||||||
if status == util.ExitError {
|
if status == svcutil.ExitError {
|
||||||
l.Warnln("Syncthing stopped with error:", app.Error())
|
l.Warnln("Syncthing stopped with error:", app.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,7 +744,7 @@ func setupSignalHandling(app *syncthing.App) {
|
|||||||
signal.Notify(restartSign, sigHup)
|
signal.Notify(restartSign, sigHup)
|
||||||
go func() {
|
go func() {
|
||||||
<-restartSign
|
<-restartSign
|
||||||
app.Stop(util.ExitRestart)
|
app.Stop(svcutil.ExitRestart)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Exit with "success" code (no restart) on INT/TERM
|
// Exit with "success" code (no restart) on INT/TERM
|
||||||
@ -753,7 +753,7 @@ func setupSignalHandling(app *syncthing.App) {
|
|||||||
signal.Notify(stopSign, os.Interrupt, sigTerm)
|
signal.Notify(stopSign, os.Interrupt, sigTerm)
|
||||||
go func() {
|
go func() {
|
||||||
<-stopSign
|
<-stopSign
|
||||||
app.Stop(util.ExitSuccess)
|
app.Stop(svcutil.ExitSuccess)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,7 +790,7 @@ func auditWriter(auditFile string) io.Writer {
|
|||||||
fd, err = os.OpenFile(auditFile, auditFlags, 0600)
|
fd, err = os.OpenFile(auditFile, auditFlags, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnln("Audit:", err)
|
l.Warnln("Audit:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
auditDest = auditFile
|
auditDest = auditFile
|
||||||
}
|
}
|
||||||
@ -840,7 +840,7 @@ func standbyMonitor(app *syncthing.App, cfg config.Wrapper) {
|
|||||||
// things a moment to stabilize.
|
// things a moment to stabilize.
|
||||||
time.Sleep(restartDelay)
|
time.Sleep(restartDelay)
|
||||||
|
|
||||||
app.Stop(util.ExitRestart)
|
app.Stop(svcutil.ExitRestart)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
@ -910,7 +910,7 @@ func autoUpgrade(cfg config.Wrapper, app *syncthing.App, evLogger events.Logger)
|
|||||||
sub.Unsubscribe()
|
sub.Unsubscribe()
|
||||||
l.Warnf("Automatically upgraded to version %q. Restarting in 1 minute.", rel.Tag)
|
l.Warnf("Automatically upgraded to version %q. Restarting in 1 minute.", rel.Tag)
|
||||||
time.Sleep(time.Minute)
|
time.Sleep(time.Minute)
|
||||||
app.Stop(util.ExitUpgrade)
|
app.Stop(svcutil.ExitUpgrade)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -998,13 +998,13 @@ func setPauseState(cfg config.Wrapper, paused bool) {
|
|||||||
}
|
}
|
||||||
if _, err := cfg.Replace(raw); err != nil {
|
if _, err := cfg.Replace(raw); err != nil {
|
||||||
l.Warnln("Cannot adjust paused state:", err)
|
l.Warnln("Cannot adjust paused state:", err)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func exitCodeForUpgrade(err error) int {
|
func exitCodeForUpgrade(err error) int {
|
||||||
if _, ok := err.(*errNoUpgrade); ok {
|
if _, ok := err.(*errNoUpgrade); ok {
|
||||||
return util.ExitNoUpgradeAvailable.AsInt()
|
return svcutil.ExitNoUpgradeAvailable.AsInt()
|
||||||
}
|
}
|
||||||
return util.ExitError.AsInt()
|
return svcutil.ExitError.AsInt()
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/locations"
|
"github.com/syncthing/syncthing/lib/locations"
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -99,7 +99,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
|||||||
|
|
||||||
if t := time.Since(restarts[0]); t < loopThreshold {
|
if t := time.Since(restarts[0]); t < loopThreshold {
|
||||||
l.Warnf("%d restarts in %v; not retrying further", countRestarts, t)
|
l.Warnf("%d restarts in %v; not retrying further", countRestarts, t)
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(restarts[0:], restarts[1:])
|
copy(restarts[0:], restarts[1:])
|
||||||
@ -169,7 +169,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
|||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Successful exit indicates an intentional shutdown
|
// Successful exit indicates an intentional shutdown
|
||||||
os.Exit(util.ExitSuccess.AsInt())
|
os.Exit(svcutil.ExitSuccess.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||||
@ -177,7 +177,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
|||||||
if stopped || runtimeOptions.noRestart {
|
if stopped || runtimeOptions.noRestart {
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
if exitCode == util.ExitUpgrade.AsInt() {
|
if exitCode == svcutil.ExitUpgrade.AsInt() {
|
||||||
// Restart the monitor process to release the .old
|
// Restart the monitor process to release the .old
|
||||||
// binary as part of the upgrade process.
|
// binary as part of the upgrade process.
|
||||||
l.Infoln("Restarting monitor...")
|
l.Infoln("Restarting monitor...")
|
||||||
@ -189,7 +189,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if runtimeOptions.noRestart {
|
if runtimeOptions.noRestart {
|
||||||
os.Exit(util.ExitError.AsInt())
|
os.Exit(svcutil.ExitError.AsInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Infoln("Syncthing exited:", err)
|
l.Infoln("Syncthing exited:", err)
|
||||||
|
@ -49,11 +49,11 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/model"
|
"github.com/syncthing/syncthing/lib/model"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/rand"
|
"github.com/syncthing/syncthing/lib/rand"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||||
"github.com/syncthing/syncthing/lib/upgrade"
|
"github.com/syncthing/syncthing/lib/upgrade"
|
||||||
"github.com/syncthing/syncthing/lib/ur"
|
"github.com/syncthing/syncthing/lib/ur"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// matches a bcrypt hash and not too much else
|
// matches a bcrypt hash and not too much else
|
||||||
@ -89,7 +89,7 @@ type service struct {
|
|||||||
startedOnce chan struct{} // the service has started successfully at least once
|
startedOnce chan struct{} // the service has started successfully at least once
|
||||||
startupErr error
|
startupErr error
|
||||||
listenerAddr net.Addr
|
listenerAddr net.Addr
|
||||||
exitChan chan *util.FatalErr
|
exitChan chan *svcutil.FatalErr
|
||||||
|
|
||||||
guiErrors logger.Recorder
|
guiErrors logger.Recorder
|
||||||
systemLog logger.Recorder
|
systemLog logger.Recorder
|
||||||
@ -123,7 +123,7 @@ func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonNam
|
|||||||
tlsDefaultCommonName: tlsDefaultCommonName,
|
tlsDefaultCommonName: tlsDefaultCommonName,
|
||||||
configChanged: make(chan struct{}),
|
configChanged: make(chan struct{}),
|
||||||
startedOnce: make(chan struct{}),
|
startedOnce: make(chan struct{}),
|
||||||
exitChan: make(chan *util.FatalErr, 1),
|
exitChan: make(chan *svcutil.FatalErr, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,7 +474,7 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) fatal(err *util.FatalErr) {
|
func (s *service) fatal(err *svcutil.FatalErr) {
|
||||||
// s.exitChan is 1-buffered and whoever is first gets handled.
|
// s.exitChan is 1-buffered and whoever is first gets handled.
|
||||||
select {
|
select {
|
||||||
case s.exitChan <- err:
|
case s.exitChan <- err:
|
||||||
@ -915,9 +915,9 @@ func (s *service) getDebugFile(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (s *service) postSystemRestart(w http.ResponseWriter, r *http.Request) {
|
func (s *service) postSystemRestart(w http.ResponseWriter, r *http.Request) {
|
||||||
s.flushResponse(`{"ok": "restarting"}`, w)
|
s.flushResponse(`{"ok": "restarting"}`, w)
|
||||||
|
|
||||||
s.fatal(&util.FatalErr{
|
s.fatal(&svcutil.FatalErr{
|
||||||
Err: errors.New("restart initiated by rest API"),
|
Err: errors.New("restart initiated by rest API"),
|
||||||
Status: util.ExitRestart,
|
Status: svcutil.ExitRestart,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,17 +944,17 @@ func (s *service) postSystemReset(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.flushResponse(`{"ok": "resetting folder `+folder+`"}`, w)
|
s.flushResponse(`{"ok": "resetting folder `+folder+`"}`, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.fatal(&util.FatalErr{
|
s.fatal(&svcutil.FatalErr{
|
||||||
Err: errors.New("restart after db reset initiated by rest API"),
|
Err: errors.New("restart after db reset initiated by rest API"),
|
||||||
Status: util.ExitRestart,
|
Status: svcutil.ExitRestart,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) postSystemShutdown(w http.ResponseWriter, r *http.Request) {
|
func (s *service) postSystemShutdown(w http.ResponseWriter, r *http.Request) {
|
||||||
s.flushResponse(`{"ok": "shutting down"}`, w)
|
s.flushResponse(`{"ok": "shutting down"}`, w)
|
||||||
s.fatal(&util.FatalErr{
|
s.fatal(&svcutil.FatalErr{
|
||||||
Err: errors.New("shutdown initiated by rest API"),
|
Err: errors.New("shutdown initiated by rest API"),
|
||||||
Status: util.ExitSuccess,
|
Status: svcutil.ExitSuccess,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1390,9 +1390,9 @@ func (s *service) postSystemUpgrade(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.flushResponse(`{"ok": "restarting"}`, w)
|
s.flushResponse(`{"ok": "restarting"}`, w)
|
||||||
s.fatal(&util.FatalErr{
|
s.fatal(&svcutil.FatalErr{
|
||||||
Err: errors.New("exit after upgrade initiated by rest API"),
|
Err: errors.New("exit after upgrade initiated by rest API"),
|
||||||
Status: util.ExitUpgrade,
|
Status: svcutil.ExitUpgrade,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,10 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/fs"
|
"github.com/syncthing/syncthing/lib/fs"
|
||||||
"github.com/syncthing/syncthing/lib/locations"
|
"github.com/syncthing/syncthing/lib/locations"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||||
"github.com/syncthing/syncthing/lib/ur"
|
"github.com/syncthing/syncthing/lib/ur"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ func TestStopAfterBrokenConfig(t *testing.T) {
|
|||||||
defer os.Remove(token)
|
defer os.Remove(token)
|
||||||
srv.started = make(chan string)
|
srv.started = make(chan string)
|
||||||
|
|
||||||
sup := suture.New("test", util.SpecWithDebugLogger(l))
|
sup := suture.New("test", svcutil.SpecWithDebugLogger(l))
|
||||||
sup.Add(srv)
|
sup.Add(srv)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
sup.ServeBackground(ctx)
|
sup.ServeBackground(ctx)
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type recv struct {
|
type recv struct {
|
||||||
@ -33,8 +33,8 @@ type Interface interface {
|
|||||||
type cast struct {
|
type cast struct {
|
||||||
*suture.Supervisor
|
*suture.Supervisor
|
||||||
name string
|
name string
|
||||||
reader util.ServiceWithError
|
reader svcutil.ServiceWithError
|
||||||
writer util.ServiceWithError
|
writer svcutil.ServiceWithError
|
||||||
outbox chan recv
|
outbox chan recv
|
||||||
inbox chan []byte
|
inbox chan []byte
|
||||||
stopped chan struct{}
|
stopped chan struct{}
|
||||||
@ -45,7 +45,7 @@ type cast struct {
|
|||||||
// methods to get a functional implementation of Interface.
|
// methods to get a functional implementation of Interface.
|
||||||
func newCast(name string) *cast {
|
func newCast(name string) *cast {
|
||||||
// Only log restarts in debug mode.
|
// Only log restarts in debug mode.
|
||||||
spec := util.SpecWithDebugLogger(l)
|
spec := svcutil.SpecWithDebugLogger(l)
|
||||||
// Don't retry too frenetically: an error to open a socket or
|
// Don't retry too frenetically: an error to open a socket or
|
||||||
// whatever is usually something that is either permanent or takes
|
// whatever is usually something that is either permanent or takes
|
||||||
// a while to get solved...
|
// a while to get solved...
|
||||||
@ -58,7 +58,7 @@ func newCast(name string) *cast {
|
|||||||
outbox: make(chan recv, 16),
|
outbox: make(chan recv, 16),
|
||||||
stopped: make(chan struct{}),
|
stopped: make(chan struct{}),
|
||||||
}
|
}
|
||||||
util.OnSupervisorDone(c.Supervisor, func() { close(c.stopped) })
|
svcutil.OnSupervisorDone(c.Supervisor, func() { close(c.stopped) })
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,8 +72,8 @@ func (c *cast) addWriter(svc func(ctx context.Context) error) {
|
|||||||
c.Add(c.writer)
|
c.Add(c.writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cast) createService(svc func(context.Context) error, suffix string) util.ServiceWithError {
|
func (c *cast) createService(svc func(context.Context) error, suffix string) svcutil.ServiceWithError {
|
||||||
return util.AsService(svc, fmt.Sprintf("%s/%s", c, suffix))
|
return svcutil.AsService(svc, fmt.Sprintf("%s/%s", c, suffix))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cast) String() string {
|
func (c *cast) String() string {
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/connections/registry"
|
"github.com/syncthing/syncthing/lib/connections/registry"
|
||||||
"github.com/syncthing/syncthing/lib/nat"
|
"github.com/syncthing/syncthing/lib/nat"
|
||||||
"github.com/syncthing/syncthing/lib/stun"
|
"github.com/syncthing/syncthing/lib/stun"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -35,7 +35,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type quicListener struct {
|
type quicListener struct {
|
||||||
util.ServiceWithError
|
svcutil.ServiceWithError
|
||||||
nat atomic.Value
|
nat atomic.Value
|
||||||
|
|
||||||
onAddressesChangedNotifier
|
onAddressesChangedNotifier
|
||||||
@ -205,7 +205,7 @@ func (f *quicListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.
|
|||||||
conns: conns,
|
conns: conns,
|
||||||
factory: f,
|
factory: f,
|
||||||
}
|
}
|
||||||
l.ServiceWithError = util.AsService(l.serve, l.String())
|
l.ServiceWithError = svcutil.AsService(l.serve, l.String())
|
||||||
l.nat.Store(stun.NATUnknown)
|
l.nat.Store(stun.NATUnknown)
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/dialer"
|
"github.com/syncthing/syncthing/lib/dialer"
|
||||||
"github.com/syncthing/syncthing/lib/nat"
|
"github.com/syncthing/syncthing/lib/nat"
|
||||||
"github.com/syncthing/syncthing/lib/relay/client"
|
"github.com/syncthing/syncthing/lib/relay/client"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -30,7 +30,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type relayListener struct {
|
type relayListener struct {
|
||||||
util.ServiceWithError
|
svcutil.ServiceWithError
|
||||||
onAddressesChangedNotifier
|
onAddressesChangedNotifier
|
||||||
|
|
||||||
uri *url.URL
|
uri *url.URL
|
||||||
@ -184,7 +184,7 @@ func (f *relayListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls
|
|||||||
conns: conns,
|
conns: conns,
|
||||||
factory: f,
|
factory: f,
|
||||||
}
|
}
|
||||||
t.ServiceWithError = util.AsService(t.serve, t.String())
|
t.ServiceWithError = svcutil.AsService(t.serve, t.String())
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/nat"
|
"github.com/syncthing/syncthing/lib/nat"
|
||||||
"github.com/syncthing/syncthing/lib/osutil"
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/util"
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ type service struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, bepProtocolName string, tlsDefaultCommonName string, evLogger events.Logger) Service {
|
func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, bepProtocolName string, tlsDefaultCommonName string, evLogger events.Logger) Service {
|
||||||
spec := util.SpecWithInfoLogger(l)
|
spec := svcutil.SpecWithInfoLogger(l)
|
||||||
service := &service{
|
service := &service{
|
||||||
Supervisor: suture.New("connections.Service", spec),
|
Supervisor: suture.New("connections.Service", spec),
|
||||||
connectionStatusHandler: newConnectionStatusHandler(),
|
connectionStatusHandler: newConnectionStatusHandler(),
|
||||||
@ -191,12 +192,12 @@ func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *t
|
|||||||
// the common handling regardless of whether the connection was
|
// the common handling regardless of whether the connection was
|
||||||
// incoming or outgoing.
|
// incoming or outgoing.
|
||||||
|
|
||||||
service.Add(util.AsService(service.connect, fmt.Sprintf("%s/connect", service)))
|
service.Add(svcutil.AsService(service.connect, fmt.Sprintf("%s/connect", service)))
|
||||||
service.Add(util.AsService(service.handle, fmt.Sprintf("%s/handle", service)))
|
service.Add(svcutil.AsService(service.handle, fmt.Sprintf("%s/handle", service)))
|
||||||
service.Add(service.listenerSupervisor)
|
service.Add(service.listenerSupervisor)
|
||||||
service.Add(service.natService)
|
service.Add(service.natService)
|
||||||
|
|
||||||
util.OnSupervisorDone(service.Supervisor, func() {
|
svcutil.OnSupervisorDone(service.Supervisor, func() {
|
||||||
service.cfg.Unsubscribe(service.limiter)
|
service.cfg.Unsubscribe(service.limiter)
|
||||||
service.cfg.Unsubscribe(service)
|
service.cfg.Unsubscribe(service)
|
||||||
})
|
})
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/connections/registry"
|
"github.com/syncthing/syncthing/lib/connections/registry"
|
||||||
"github.com/syncthing/syncthing/lib/dialer"
|
"github.com/syncthing/syncthing/lib/dialer"
|
||||||
"github.com/syncthing/syncthing/lib/nat"
|
"github.com/syncthing/syncthing/lib/nat"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -29,7 +29,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type tcpListener struct {
|
type tcpListener struct {
|
||||||
util.ServiceWithError
|
svcutil.ServiceWithError
|
||||||
onAddressesChangedNotifier
|
onAddressesChangedNotifier
|
||||||
|
|
||||||
uri *url.URL
|
uri *url.URL
|
||||||
@ -207,7 +207,7 @@ func (f *tcpListenerFactory) New(uri *url.URL, cfg config.Wrapper, tlsCfg *tls.C
|
|||||||
natService: natService,
|
natService: natService,
|
||||||
factory: f,
|
factory: f,
|
||||||
}
|
}
|
||||||
l.ServiceWithError = util.AsService(l.serve, l.String())
|
l.ServiceWithError = svcutil.AsService(l.serve, l.String())
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/rand"
|
"github.com/syncthing/syncthing/lib/rand"
|
||||||
"github.com/syncthing/syncthing/lib/sha256"
|
"github.com/syncthing/syncthing/lib/sha256"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/util"
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
@ -73,7 +74,7 @@ type Lowlevel struct {
|
|||||||
|
|
||||||
func NewLowlevel(backend backend.Backend, evLogger events.Logger, opts ...Option) (*Lowlevel, error) {
|
func NewLowlevel(backend backend.Backend, evLogger events.Logger, opts ...Option) (*Lowlevel, error) {
|
||||||
// Only log restarts in debug mode.
|
// Only log restarts in debug mode.
|
||||||
spec := util.SpecWithDebugLogger(l)
|
spec := svcutil.SpecWithDebugLogger(l)
|
||||||
db := &Lowlevel{
|
db := &Lowlevel{
|
||||||
Supervisor: suture.New("db.Lowlevel", spec),
|
Supervisor: suture.New("db.Lowlevel", spec),
|
||||||
Backend: backend,
|
Backend: backend,
|
||||||
@ -89,7 +90,7 @@ func NewLowlevel(backend backend.Backend, evLogger events.Logger, opts ...Option
|
|||||||
opt(db)
|
opt(db)
|
||||||
}
|
}
|
||||||
db.keyer = newDefaultKeyer(db.folderIdx, db.deviceIdx)
|
db.keyer = newDefaultKeyer(db.folderIdx, db.deviceIdx)
|
||||||
db.Add(util.AsService(db.gcRunner, "db.Lowlevel/gcRunner"))
|
db.Add(svcutil.AsService(db.gcRunner, "db.Lowlevel/gcRunner"))
|
||||||
if path := db.needsRepairPath(); path != "" {
|
if path := db.needsRepairPath(); path != "" {
|
||||||
if _, err := os.Lstat(path); err == nil {
|
if _, err := os.Lstat(path); err == nil {
|
||||||
l.Infoln("Database was marked for repair - this may take a while")
|
l.Infoln("Database was marked for repair - this may take a while")
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/rand"
|
"github.com/syncthing/syncthing/lib/rand"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ const (
|
|||||||
|
|
||||||
func NewLocal(id protocol.DeviceID, addr string, addrList AddressLister, evLogger events.Logger) (FinderService, error) {
|
func NewLocal(id protocol.DeviceID, addr string, addrList AddressLister, evLogger events.Logger) (FinderService, error) {
|
||||||
c := &localClient{
|
c := &localClient{
|
||||||
Supervisor: suture.New("local", util.SpecWithDebugLogger(l)),
|
Supervisor: suture.New("local", svcutil.SpecWithDebugLogger(l)),
|
||||||
myID: id,
|
myID: id,
|
||||||
addrList: addrList,
|
addrList: addrList,
|
||||||
evLogger: evLogger,
|
evLogger: evLogger,
|
||||||
@ -81,9 +81,9 @@ func NewLocal(id protocol.DeviceID, addr string, addrList AddressLister, evLogge
|
|||||||
c.beacon = beacon.NewMulticast(addr)
|
c.beacon = beacon.NewMulticast(addr)
|
||||||
}
|
}
|
||||||
c.Add(c.beacon)
|
c.Add(c.beacon)
|
||||||
c.Add(util.AsService(c.recvAnnouncements, fmt.Sprintf("%s/recv", c)))
|
c.Add(svcutil.AsService(c.recvAnnouncements, fmt.Sprintf("%s/recv", c)))
|
||||||
|
|
||||||
c.Add(util.AsService(c.sendLocalAnnouncements, fmt.Sprintf("%s/sendLocal", c)))
|
c.Add(svcutil.AsService(c.sendLocalAnnouncements, fmt.Sprintf("%s/sendLocal", c)))
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/config"
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/util"
|
||||||
)
|
)
|
||||||
@ -47,7 +48,7 @@ type manager struct {
|
|||||||
|
|
||||||
func NewManager(myID protocol.DeviceID, cfg config.Wrapper, cert tls.Certificate, evLogger events.Logger, lister AddressLister) Manager {
|
func NewManager(myID protocol.DeviceID, cfg config.Wrapper, cert tls.Certificate, evLogger events.Logger, lister AddressLister) Manager {
|
||||||
m := &manager{
|
m := &manager{
|
||||||
Supervisor: suture.New("discover.Manager", util.SpecWithDebugLogger(l)),
|
Supervisor: suture.New("discover.Manager", svcutil.SpecWithDebugLogger(l)),
|
||||||
myID: myID,
|
myID: myID,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
cert: cert,
|
cert: cert,
|
||||||
@ -57,7 +58,7 @@ func NewManager(myID protocol.DeviceID, cfg config.Wrapper, cert tls.Certificate
|
|||||||
finders: make(map[string]cachedFinder),
|
finders: make(map[string]cachedFinder),
|
||||||
mut: sync.NewRWMutex(),
|
mut: sync.NewRWMutex(),
|
||||||
}
|
}
|
||||||
m.Add(util.AsService(m.serve, m.String()))
|
m.Add(svcutil.AsService(m.serve, m.String()))
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/db"
|
"github.com/syncthing/syncthing/lib/db"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxDurationSinceLastEventReq = time.Minute
|
const maxDurationSinceLastEventReq = time.Minute
|
||||||
@ -52,7 +52,7 @@ type folderSummaryService struct {
|
|||||||
|
|
||||||
func NewFolderSummaryService(cfg config.Wrapper, m Model, id protocol.DeviceID, evLogger events.Logger) FolderSummaryService {
|
func NewFolderSummaryService(cfg config.Wrapper, m Model, id protocol.DeviceID, evLogger events.Logger) FolderSummaryService {
|
||||||
service := &folderSummaryService{
|
service := &folderSummaryService{
|
||||||
Supervisor: suture.New("folderSummaryService", util.SpecWithDebugLogger(l)),
|
Supervisor: suture.New("folderSummaryService", svcutil.SpecWithDebugLogger(l)),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
model: m,
|
model: m,
|
||||||
id: id,
|
id: id,
|
||||||
@ -63,8 +63,8 @@ func NewFolderSummaryService(cfg config.Wrapper, m Model, id protocol.DeviceID,
|
|||||||
lastEventReqMut: sync.NewMutex(),
|
lastEventReqMut: sync.NewMutex(),
|
||||||
}
|
}
|
||||||
|
|
||||||
service.Add(util.AsService(service.listenForUpdates, fmt.Sprintf("%s/listenForUpdates", service)))
|
service.Add(svcutil.AsService(service.listenForUpdates, fmt.Sprintf("%s/listenForUpdates", service)))
|
||||||
service.Add(util.AsService(service.calculateSummaries, fmt.Sprintf("%s/calculateSummaries", service)))
|
service.Add(svcutil.AsService(service.calculateSummaries, fmt.Sprintf("%s/calculateSummaries", service)))
|
||||||
|
|
||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/db"
|
"github.com/syncthing/syncthing/lib/db"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type indexSender struct {
|
type indexSender struct {
|
||||||
@ -38,7 +38,7 @@ type indexSender struct {
|
|||||||
func (s *indexSender) Serve(ctx context.Context) (err error) {
|
func (s *indexSender) Serve(ctx context.Context) (err error) {
|
||||||
l.Debugf("Starting indexSender for %s to %s at %s (slv=%d)", s.folder, s.conn.ID(), s.conn, s.prevSequence)
|
l.Debugf("Starting indexSender for %s to %s at %s (slv=%d)", s.folder, s.conn.ID(), s.conn, s.prevSequence)
|
||||||
defer func() {
|
defer func() {
|
||||||
err = util.NoRestartErr(err)
|
err = svcutil.NoRestartErr(err)
|
||||||
l.Debugf("Exiting indexSender for %s to %s at %s: %v", s.folder, s.conn.ID(), s.conn, err)
|
l.Debugf("Exiting indexSender for %s to %s at %s: %v", s.folder, s.conn.ID(), s.conn, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/scanner"
|
"github.com/syncthing/syncthing/lib/scanner"
|
||||||
"github.com/syncthing/syncthing/lib/stats"
|
"github.com/syncthing/syncthing/lib/stats"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/ur/contract"
|
"github.com/syncthing/syncthing/lib/ur/contract"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
"github.com/syncthing/syncthing/lib/versioner"
|
"github.com/syncthing/syncthing/lib/versioner"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ var (
|
|||||||
// where it sends index information to connected peers and responds to requests
|
// where it sends index information to connected peers and responds to requests
|
||||||
// for file data without altering the local folder in any way.
|
// for file data without altering the local folder in any way.
|
||||||
func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersion string, ldb *db.Lowlevel, protectedFiles []string, evLogger events.Logger) Model {
|
func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersion string, ldb *db.Lowlevel, protectedFiles []string, evLogger events.Logger) Model {
|
||||||
spec := util.SpecWithDebugLogger(l)
|
spec := svcutil.SpecWithDebugLogger(l)
|
||||||
m := &model{
|
m := &model{
|
||||||
Supervisor: suture.New("model", spec),
|
Supervisor: suture.New("model", spec),
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ func NewModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersio
|
|||||||
m.deviceStatRefs[devID] = stats.NewDeviceStatisticsReference(m.db, devID.String())
|
m.deviceStatRefs[devID] = stats.NewDeviceStatisticsReference(m.db, devID.String())
|
||||||
}
|
}
|
||||||
m.Add(m.progressEmitter)
|
m.Add(m.progressEmitter)
|
||||||
m.Add(util.AsService(m.serve, m.String()))
|
m.Add(svcutil.AsService(m.serve, m.String()))
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
@ -262,7 +262,7 @@ func (m *model) serve(ctx context.Context) error {
|
|||||||
|
|
||||||
if err := m.initFolders(); err != nil {
|
if err := m.initFolders(); err != nil {
|
||||||
close(m.started)
|
close(m.started)
|
||||||
return util.AsFatalErr(err, util.ExitError)
|
return svcutil.AsFatalErr(err, svcutil.ExitError)
|
||||||
}
|
}
|
||||||
|
|
||||||
close(m.started)
|
close(m.started)
|
||||||
@ -271,7 +271,7 @@ func (m *model) serve(ctx context.Context) error {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case err := <-m.fatalChan:
|
case err := <-m.fatalChan:
|
||||||
return util.AsFatalErr(err, util.ExitError)
|
return svcutil.AsFatalErr(err, svcutil.ExitError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/relay/protocol"
|
"github.com/syncthing/syncthing/lib/relay/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
|
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
)
|
)
|
||||||
@ -45,7 +45,7 @@ func NewClient(uri *url.URL, certs []tls.Certificate, invitations chan protocol.
|
|||||||
}
|
}
|
||||||
|
|
||||||
type commonClient struct {
|
type commonClient struct {
|
||||||
util.ServiceWithError
|
svcutil.ServiceWithError
|
||||||
|
|
||||||
invitations chan protocol.SessionInvitation
|
invitations chan protocol.SessionInvitation
|
||||||
closeInvitationsOnFinish bool
|
closeInvitationsOnFinish bool
|
||||||
@ -61,7 +61,7 @@ func newCommonClient(invitations chan protocol.SessionInvitation, serve func(con
|
|||||||
defer c.cleanup()
|
defer c.cleanup()
|
||||||
return serve(ctx)
|
return serve(ctx)
|
||||||
}
|
}
|
||||||
c.ServiceWithError = util.AsService(newServe, creator)
|
c.ServiceWithError = svcutil.AsService(newServe, creator)
|
||||||
if c.invitations == nil {
|
if c.invitations == nil {
|
||||||
c.closeInvitationsOnFinish = true
|
c.closeInvitationsOnFinish = true
|
||||||
c.invitations = make(chan protocol.SessionInvitation)
|
c.invitations = make(chan protocol.SessionInvitation)
|
||||||
|
177
lib/svcutil/svcutil.go
Normal file
177
lib/svcutil/svcutil.go
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
// Copyright (C) 2016 The Syncthing Authors.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package svcutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/syncthing/syncthing/lib/logger"
|
||||||
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
|
|
||||||
|
"github.com/thejerf/suture/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ServiceTimeout = 10 * time.Second
|
||||||
|
|
||||||
|
type FatalErr struct {
|
||||||
|
Err error
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *FatalErr) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *FatalErr) Is(target error) bool {
|
||||||
|
return target == suture.ErrTerminateSupervisorTree
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoRestartErr wraps the given error err (which may be nil) to make sure that
|
||||||
|
// `errors.Is(err, suture.ErrDoNotRestart) == true`.
|
||||||
|
func NoRestartErr(err error) error {
|
||||||
|
if err == nil {
|
||||||
|
return suture.ErrDoNotRestart
|
||||||
|
}
|
||||||
|
return &noRestartErr{err}
|
||||||
|
}
|
||||||
|
|
||||||
|
type noRestartErr struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *noRestartErr) Error() string {
|
||||||
|
return e.err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *noRestartErr) Unwrap() error {
|
||||||
|
return e.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *noRestartErr) Is(target error) bool {
|
||||||
|
return target == suture.ErrDoNotRestart
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExitStatus int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExitSuccess ExitStatus = 0
|
||||||
|
ExitError ExitStatus = 1
|
||||||
|
ExitNoUpgradeAvailable ExitStatus = 2
|
||||||
|
ExitRestart ExitStatus = 3
|
||||||
|
ExitUpgrade ExitStatus = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
Timeout: ServiceTimeout,
|
||||||
|
PassThroughPanics: true,
|
||||||
|
DontPropagateTermination: false,
|
||||||
|
}
|
||||||
|
}
|
@ -37,10 +37,10 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/rand"
|
"github.com/syncthing/syncthing/lib/rand"
|
||||||
"github.com/syncthing/syncthing/lib/sha256"
|
"github.com/syncthing/syncthing/lib/sha256"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||||
"github.com/syncthing/syncthing/lib/upgrade"
|
"github.com/syncthing/syncthing/lib/upgrade"
|
||||||
"github.com/syncthing/syncthing/lib/ur"
|
"github.com/syncthing/syncthing/lib/ur"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -73,7 +73,7 @@ type App struct {
|
|||||||
evLogger events.Logger
|
evLogger events.Logger
|
||||||
cert tls.Certificate
|
cert tls.Certificate
|
||||||
opts Options
|
opts Options
|
||||||
exitStatus util.ExitStatus
|
exitStatus svcutil.ExitStatus
|
||||||
err error
|
err error
|
||||||
stopOnce sync.Once
|
stopOnce sync.Once
|
||||||
mainServiceCancel context.CancelFunc
|
mainServiceCancel context.CancelFunc
|
||||||
@ -103,7 +103,7 @@ func New(cfg config.Wrapper, dbBackend backend.Backend, evLogger events.Logger,
|
|||||||
func (a *App) Start() error {
|
func (a *App) Start() error {
|
||||||
// Create a main service manager. We'll add things to this as we go along.
|
// Create a main service manager. We'll add things to this as we go along.
|
||||||
// We want any logging it does to go through our log system.
|
// We want any logging it does to go through our log system.
|
||||||
spec := util.SpecWithDebugLogger(l)
|
spec := svcutil.SpecWithDebugLogger(l)
|
||||||
a.mainService = suture.New("main", spec)
|
a.mainService = suture.New("main", spec)
|
||||||
|
|
||||||
// Start the supervisor and wait for it to stop to handle cleanup.
|
// Start the supervisor and wait for it to stop to handle cleanup.
|
||||||
@ -113,7 +113,7 @@ func (a *App) Start() error {
|
|||||||
go a.run(ctx)
|
go a.run(ctx)
|
||||||
|
|
||||||
if err := a.startup(); err != nil {
|
if err := a.startup(); err != nil {
|
||||||
a.stopWithErr(util.ExitError, err)
|
a.stopWithErr(svcutil.ExitError, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,19 +355,19 @@ func (a *App) handleMainServiceError(err error) {
|
|||||||
if err == nil || errors.Is(err, context.Canceled) {
|
if err == nil || errors.Is(err, context.Canceled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var fatalErr *util.FatalErr
|
var fatalErr *svcutil.FatalErr
|
||||||
if errors.As(err, &fatalErr) {
|
if errors.As(err, &fatalErr) {
|
||||||
a.exitStatus = fatalErr.Status
|
a.exitStatus = fatalErr.Status
|
||||||
a.err = fatalErr.Err
|
a.err = fatalErr.Err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a.err = err
|
a.err = err
|
||||||
a.exitStatus = util.ExitError
|
a.exitStatus = svcutil.ExitError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait blocks until the app stops running. Also returns if the app hasn't been
|
// Wait blocks until the app stops running. Also returns if the app hasn't been
|
||||||
// started yet.
|
// started yet.
|
||||||
func (a *App) Wait() util.ExitStatus {
|
func (a *App) Wait() svcutil.ExitStatus {
|
||||||
<-a.stopped
|
<-a.stopped
|
||||||
return a.exitStatus
|
return a.exitStatus
|
||||||
}
|
}
|
||||||
@ -385,11 +385,11 @@ func (a *App) Error() error {
|
|||||||
|
|
||||||
// Stop stops the app and sets its exit status to given reason, unless the app
|
// Stop stops the app and sets its exit status to given reason, unless the app
|
||||||
// was already stopped before. In any case it returns the effective exit status.
|
// was already stopped before. In any case it returns the effective exit status.
|
||||||
func (a *App) Stop(stopReason util.ExitStatus) util.ExitStatus {
|
func (a *App) Stop(stopReason svcutil.ExitStatus) svcutil.ExitStatus {
|
||||||
return a.stopWithErr(stopReason, nil)
|
return a.stopWithErr(stopReason, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) stopWithErr(stopReason util.ExitStatus, err error) util.ExitStatus {
|
func (a *App) stopWithErr(stopReason svcutil.ExitStatus, err error) svcutil.ExitStatus {
|
||||||
a.stopOnce.Do(func() {
|
a.stopOnce.Do(func() {
|
||||||
a.exitStatus = stopReason
|
a.exitStatus = stopReason
|
||||||
a.err = err
|
a.err = err
|
||||||
|
@ -17,8 +17,8 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/db/backend"
|
"github.com/syncthing/syncthing/lib/db/backend"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||||
"github.com/syncthing/syncthing/lib/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func tempCfgFilename(t *testing.T) string {
|
func tempCfgFilename(t *testing.T) string {
|
||||||
@ -90,7 +90,7 @@ func TestStartupFail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
var waitE util.ExitStatus
|
var waitE svcutil.ExitStatus
|
||||||
go func() {
|
go func() {
|
||||||
waitE = app.Wait()
|
waitE = app.Wait()
|
||||||
close(done)
|
close(done)
|
||||||
@ -102,8 +102,8 @@ func TestStartupFail(t *testing.T) {
|
|||||||
case <-done:
|
case <-done:
|
||||||
}
|
}
|
||||||
|
|
||||||
if waitE != util.ExitError {
|
if waitE != svcutil.ExitError {
|
||||||
t.Errorf("Got exit status %v, expected %v", waitE, util.ExitError)
|
t.Errorf("Got exit status %v, expected %v", waitE, svcutil.ExitError)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = app.Error(); err != startErr {
|
if err = app.Error(); err != startErr {
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/config"
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/dialer"
|
"github.com/syncthing/syncthing/lib/dialer"
|
||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
|
"github.com/syncthing/syncthing/lib/svcutil"
|
||||||
|
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
)
|
)
|
||||||
@ -28,6 +29,7 @@ var (
|
|||||||
minDelay = 10 * time.Second
|
minDelay = 10 * time.Second
|
||||||
maxDelay = time.Minute
|
maxDelay = time.Minute
|
||||||
sendTimeout = time.Minute
|
sendTimeout = time.Minute
|
||||||
|
finalSendTimeout = svcutil.ServiceTimeout / 2
|
||||||
evChanClosed = "failure event channel closed"
|
evChanClosed = "failure event channel closed"
|
||||||
invalidEventDataType = "failure event data is not a string"
|
invalidEventDataType = "failure event data is not a string"
|
||||||
)
|
)
|
||||||
@ -116,11 +118,7 @@ outer:
|
|||||||
now := time.Now()
|
now := time.Now()
|
||||||
for descr, stat := range h.buf {
|
for descr, stat := range h.buf {
|
||||||
if now.Sub(stat.last) > minDelay || now.Sub(stat.first) > maxDelay {
|
if now.Sub(stat.last) > minDelay || now.Sub(stat.first) > maxDelay {
|
||||||
reports = append(reports, FailureReport{
|
reports = append(reports, newFailureReport(descr, stat.count))
|
||||||
Description: descr,
|
|
||||||
Count: stat.count,
|
|
||||||
Version: build.LongVersion,
|
|
||||||
})
|
|
||||||
delete(h.buf, descr)
|
delete(h.buf, descr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,6 +143,13 @@ outer:
|
|||||||
|
|
||||||
if sub != nil {
|
if sub != nil {
|
||||||
sub.Unsubscribe()
|
sub.Unsubscribe()
|
||||||
|
reports := make([]FailureReport, 0, len(h.buf))
|
||||||
|
for descr, stat := range h.buf {
|
||||||
|
reports = append(reports, newFailureReport(descr, stat.count))
|
||||||
|
}
|
||||||
|
timeout, cancel := context.WithTimeout(context.Background(), finalSendTimeout)
|
||||||
|
defer cancel()
|
||||||
|
sendFailureReports(timeout, reports, url)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -207,3 +212,11 @@ func sendFailureReports(ctx context.Context, reports []FailureReport, url string
|
|||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newFailureReport(descr string, count int) FailureReport {
|
||||||
|
return FailureReport{
|
||||||
|
Description: descr,
|
||||||
|
Count: count,
|
||||||
|
Version: build.LongVersion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,7 +8,6 @@ package util
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -17,9 +16,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/logger"
|
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
|
||||||
|
|
||||||
"github.com/thejerf/suture/v4"
|
"github.com/thejerf/suture/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -263,19 +259,6 @@ type FatalErr struct {
|
|||||||
Status ExitStatus
|
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 {
|
func (e *FatalErr) Error() string {
|
||||||
return e.Err.Error()
|
return e.Err.Error()
|
||||||
}
|
}
|
||||||
@ -327,61 +310,6 @@ func (s ExitStatus) AsInt() int {
|
|||||||
return int(s)
|
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.
|
// OnDone calls fn when ctx is cancelled.
|
||||||
func OnDone(ctx context.Context, fn func()) {
|
func OnDone(ctx context.Context, fn func()) {
|
||||||
go 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 {
|
func CallWithContext(ctx context.Context, fn func() error) error {
|
||||||
var err error
|
var err error
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
Loading…
Reference in New Issue
Block a user