diff --git a/lib/api/api.go b/lib/api/api.go index f09df33f3..b5be612e1 100644 --- a/lib/api/api.go +++ b/lib/api/api.go @@ -92,6 +92,7 @@ type service struct { listenerAddr net.Addr exitChan chan *svcutil.FatalErr miscDB *db.NamespacedKV + shutdownTimeout time.Duration guiErrors logger.Recorder systemLog logger.Recorder @@ -129,6 +130,7 @@ func New(id protocol.DeviceID, cfg config.Wrapper, assetDir, tlsDefaultCommonNam startedOnce: make(chan struct{}), exitChan: make(chan *svcutil.FatalErr, 1), miscDB: miscDB, + shutdownTimeout: 100 * time.Millisecond, } } @@ -451,7 +453,7 @@ func (s *service) Serve(ctx context.Context) error { } // Give it a moment to shut down gracefully, e.g. if we are restarting // due to a config change through the API, let that finish successfully. - timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + timeout, cancel := context.WithTimeout(context.Background(), s.shutdownTimeout) defer cancel() if err := srv.Shutdown(timeout); err == timeout.Err() { srv.Close() diff --git a/lib/api/api_test.go b/lib/api/api_test.go index 56b8bec50..db5df4963 100644 --- a/lib/api/api_test.go +++ b/lib/api/api_test.go @@ -937,6 +937,10 @@ func TestApiCache(t *testing.T) { } func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) { + return startHTTPWithShutdownTimeout(cfg, 0) +} + +func startHTTPWithShutdownTimeout(cfg config.Wrapper, shutdownTimeout time.Duration) (string, context.CancelFunc, error) { m := new(modelmocks.Model) assetDir := "../../gui" eventSub := new(eventmocks.BufferedSubscription) @@ -964,6 +968,10 @@ func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) { svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, mockedSummary, errorLog, systemLog, false, kdb).(*service) svc.started = addrChan + if shutdownTimeout > 0*time.Millisecond { + svc.shutdownTimeout = shutdownTimeout + } + // Actually start the API service supervisor := suture.New("API test", suture.Spec{ PassThroughPanics: true,