cmd/syncthing: Delay browser start until the GUI is ready (fixes #3619)
This commit is contained in:
parent
54d4010f1a
commit
215503b4f7
|
@ -61,7 +61,7 @@ type apiService struct {
|
||||||
stop chan struct{} // signals intentional stop
|
stop chan struct{} // signals intentional stop
|
||||||
configChanged chan struct{} // signals intentional listener close due to config change
|
configChanged chan struct{} // signals intentional listener close due to config change
|
||||||
started chan string // signals startup complete by sending the listener address, for testing only
|
started chan string // signals startup complete by sending the listener address, for testing only
|
||||||
startedOnce bool // the service has started successfully at least once
|
startedOnce chan struct{} // the service has started successfully at least once
|
||||||
|
|
||||||
guiErrors logger.Recorder
|
guiErrors logger.Recorder
|
||||||
systemLog logger.Recorder
|
systemLog logger.Recorder
|
||||||
|
@ -129,6 +129,7 @@ func newAPIService(id protocol.DeviceID, cfg configIntf, httpsCertFile, httpsKey
|
||||||
systemConfigMut: sync.NewMutex(),
|
systemConfigMut: sync.NewMutex(),
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
configChanged: make(chan struct{}),
|
configChanged: make(chan struct{}),
|
||||||
|
startedOnce: make(chan struct{}),
|
||||||
guiErrors: errors,
|
guiErrors: errors,
|
||||||
systemLog: systemLog,
|
systemLog: systemLog,
|
||||||
}
|
}
|
||||||
|
@ -202,20 +203,20 @@ func sendJSON(w http.ResponseWriter, jsonObject interface{}) {
|
||||||
func (s *apiService) Serve() {
|
func (s *apiService) Serve() {
|
||||||
listener, err := s.getListener(s.cfg.GUI())
|
listener, err := s.getListener(s.cfg.GUI())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !s.startedOnce {
|
select {
|
||||||
|
case <-s.startedOnce:
|
||||||
|
// We let this be a loud user-visible warning as it may be the only
|
||||||
|
// indication they get that the GUI won't be available.
|
||||||
|
l.Warnln("Starting API/GUI:", err)
|
||||||
|
return
|
||||||
|
|
||||||
|
default:
|
||||||
// This is during initialization. A failure here should be fatal
|
// This is during initialization. A failure here should be fatal
|
||||||
// as there will be no way for the user to communicate with us
|
// as there will be no way for the user to communicate with us
|
||||||
// otherwise anyway.
|
// otherwise anyway.
|
||||||
l.Fatalln("Starting API/GUI:", err)
|
l.Fatalln("Starting API/GUI:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We let this be a loud user-visible warning as it may be the only
|
|
||||||
// indication they get that the GUI won't be available on startup.
|
|
||||||
l.Warnln("Starting API/GUI:", err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
s.startedOnce = true
|
|
||||||
defer listener.Close()
|
|
||||||
|
|
||||||
if listener == nil {
|
if listener == nil {
|
||||||
// Not much we can do here other than exit quickly. The supervisor
|
// Not much we can do here other than exit quickly. The supervisor
|
||||||
|
@ -223,6 +224,8 @@ func (s *apiService) Serve() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer listener.Close()
|
||||||
|
|
||||||
// The GET handlers
|
// The GET handlers
|
||||||
getRestMux := http.NewServeMux()
|
getRestMux := http.NewServeMux()
|
||||||
getRestMux.HandleFunc("/rest/db/completion", s.getDBCompletion) // device folder
|
getRestMux.HandleFunc("/rest/db/completion", s.getDBCompletion) // device folder
|
||||||
|
@ -339,6 +342,14 @@ func (s *apiService) Serve() {
|
||||||
s.started <- listener.Addr().String()
|
s.started <- listener.Addr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indicate successfull initial startup, to ourselves and to interested
|
||||||
|
// listeners (i.e. the thing that starts the browser).
|
||||||
|
select {
|
||||||
|
case <-s.startedOnce:
|
||||||
|
default:
|
||||||
|
close(s.startedOnce)
|
||||||
|
}
|
||||||
|
|
||||||
// Serve in the background
|
// Serve in the background
|
||||||
|
|
||||||
serveError := make(chan error, 1)
|
serveError := make(chan error, 1)
|
||||||
|
|
|
@ -947,6 +947,7 @@ func setupGUI(mainService *suture.Supervisor, cfg *config.Wrapper, m *model.Mode
|
||||||
if cfg.Options().StartBrowser && !runtimeOptions.noBrowser && !runtimeOptions.stRestarting {
|
if cfg.Options().StartBrowser && !runtimeOptions.noBrowser && !runtimeOptions.stRestarting {
|
||||||
// Can potentially block if the utility we are invoking doesn't
|
// Can potentially block if the utility we are invoking doesn't
|
||||||
// fork, and just execs, hence keep it in it's own routine.
|
// fork, and just execs, hence keep it in it's own routine.
|
||||||
|
<-api.startedOnce
|
||||||
go openURL(guiCfg.URL())
|
go openURL(guiCfg.URL())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue