UPSTREAM: 91984: genericapiserver library must wait for server.Shutdown
@@ -340,7 +340,7 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error {
}()
// close socket after delayed stopCh
- err := s.NonBlockingRun(delayedStopCh)
+ stoppedCh, err := s.NonBlockingRun(delayedStopCh)
if err != nil {
return err
}
@@ -361,6 +361,8 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error {
// wait for the delayed stopCh before closing the handler chain (it rejects everything after Wait has been called).
<-delayedStopCh
+ // wait for stoppedCh that is closed when the graceful termination (server.Shutdown) is finished.
+ <-stoppedCh
// Wait for all requests to finish, which are bounded by the RequestTimeout variable.
s.HandlerChainWaitGroup.Wait()
@@ -371,7 +373,8 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error {
// NonBlockingRun spawns the secure http server. An error is
// returned if the secure port cannot be listened on.
-func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
+// The returned channel is closed when the (asynchronous) termination is finished.
+func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) (<-chan struct{}, error) {
// Use an stop channel to allow graceful shutdown without dropping audit events
// after http server shutdown.
auditStopCh := make(chan struct{})
@@ -380,7 +383,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
// before http server start serving. Otherwise the Backend.ProcessEvents call might block.
if s.AuditBackend != nil {
if err := s.AuditBackend.Run(auditStopCh); err != nil {
- return fmt.Errorf("failed to run the audit backend: %v", err)
+ return nil, fmt.Errorf("failed to run the audit backend: %v", err)
}
}
@@ -393,7 +396,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
if err != nil {
close(internalStopCh)
close(auditStopCh)
- return err
+ return nil, err
}
}
@@ -416,7 +419,7 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
klog.Errorf("Unable to send systemd daemon successful start message: %v\n", err)
}
- return nil
+ return stoppedCh, nil
}
// installAPIResources is a private method for installing the REST storage backing each api groupversionresource
