github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/cli/server_unix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package cli
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"os/signal"
    10  	"syscall"
    11  	"time"
    12  
    13  	"github.com/pyroscope-io/pyroscope/pkg/config"
    14  )
    15  
    16  func NewServer(c *config.Server) (*Server, error) {
    17  	svc, err := newServerService(c)
    18  	if err != nil {
    19  		return nil, fmt.Errorf("could not initialize server: %w", err)
    20  	}
    21  	return &Server{svc: svc}, nil
    22  }
    23  
    24  func (s *Server) Stop() { s.svc.Stop() }
    25  
    26  func (s *Server) Start() error {
    27  	exited := make(chan error)
    28  	go func() {
    29  		exited <- s.svc.Start()
    30  		close(exited)
    31  	}()
    32  
    33  	sigs := make(chan os.Signal, 1)
    34  	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    35  	for {
    36  		select {
    37  		case err := <-exited:
    38  			return err
    39  
    40  		case <-sigs:
    41  			s.svc.logger.Info("stopping server")
    42  			stopTime := time.Now()
    43  			s.svc.Stop()
    44  			if err := <-exited; err != nil {
    45  				s.svc.logger.WithError(err).Error("failed to stop server gracefully")
    46  				return err
    47  			}
    48  			s.svc.logger.WithField("duration", time.Since(stopTime)).Info("server stopped gracefully")
    49  			return nil
    50  		}
    51  	}
    52  }