storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/signals.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2015-2019 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"net/http"
    23  	"os"
    24  	"strings"
    25  
    26  	"storj.io/minio/cmd/logger"
    27  )
    28  
    29  func handleSignals() {
    30  	// Custom exit function
    31  	exit := func(success bool) {
    32  		// If global profiler is set stop before we exit.
    33  		globalProfilerMu.Lock()
    34  		defer globalProfilerMu.Unlock()
    35  		for _, p := range globalProfiler {
    36  			p.Stop()
    37  		}
    38  
    39  		if success {
    40  			os.Exit(0)
    41  		}
    42  
    43  		os.Exit(1)
    44  	}
    45  
    46  	stopProcess := func() bool {
    47  		var err, oerr error
    48  
    49  		// send signal to various go-routines that they need to quit.
    50  		cancelGlobalContext()
    51  
    52  		if GlobalNotificationSys != nil {
    53  			GlobalNotificationSys.RemoveAllRemoteTargets()
    54  		}
    55  
    56  		if httpServer := newHTTPServerFn(); httpServer != nil {
    57  			err = httpServer.Shutdown()
    58  			if !errors.Is(err, http.ErrServerClosed) {
    59  				logger.LogIf(context.Background(), err)
    60  			}
    61  		}
    62  
    63  		if objAPI := newObjectLayerFn(); objAPI != nil {
    64  			oerr = objAPI.Shutdown(context.Background())
    65  			logger.LogIf(context.Background(), oerr)
    66  		}
    67  
    68  		return (err == nil && oerr == nil)
    69  	}
    70  
    71  	for {
    72  		select {
    73  		case <-globalHTTPServerErrorCh:
    74  			exit(stopProcess())
    75  		case osSignal := <-globalOSSignalCh:
    76  			logger.Info("Exiting on signal: %s", strings.ToUpper(osSignal.String()))
    77  			exit(stopProcess())
    78  		case signal := <-globalServiceSignalCh:
    79  			switch signal {
    80  			case serviceRestart:
    81  				logger.Info("Restarting on service signal")
    82  				stop := stopProcess()
    83  				rerr := restartProcess()
    84  				logger.LogIf(context.Background(), rerr)
    85  				exit(stop && rerr == nil)
    86  			case serviceStop:
    87  				logger.Info("Stopping on service signal")
    88  				exit(stopProcess())
    89  			}
    90  		}
    91  	}
    92  }