github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/container/health.go (about)

     1  package container // import "github.com/docker/docker/container"
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/docker/docker/api/types"
     7  	"github.com/sirupsen/logrus"
     8  )
     9  
    10  // Health holds the current container health-check state
    11  type Health struct {
    12  	types.Health
    13  	stop chan struct{} // Write struct{} to stop the monitor
    14  	mu   sync.Mutex
    15  }
    16  
    17  // String returns a human-readable description of the health-check state
    18  func (s *Health) String() string {
    19  	status := s.Status()
    20  
    21  	switch status {
    22  	case types.Starting:
    23  		return "health: starting"
    24  	default: // Healthy and Unhealthy are clear on their own
    25  		return status
    26  	}
    27  }
    28  
    29  // Status returns the current health status.
    30  //
    31  // Note that this takes a lock and the value may change after being read.
    32  func (s *Health) Status() string {
    33  	s.mu.Lock()
    34  	defer s.mu.Unlock()
    35  
    36  	// This happens when the monitor has yet to be setup.
    37  	if s.Health.Status == "" {
    38  		return types.Unhealthy
    39  	}
    40  
    41  	return s.Health.Status
    42  }
    43  
    44  // SetStatus writes the current status to the underlying health structure,
    45  // obeying the locking semantics.
    46  //
    47  // Status may be set directly if another lock is used.
    48  func (s *Health) SetStatus(new string) {
    49  	s.mu.Lock()
    50  	defer s.mu.Unlock()
    51  
    52  	s.Health.Status = new
    53  }
    54  
    55  // OpenMonitorChannel creates and returns a new monitor channel. If there
    56  // already is one, it returns nil.
    57  func (s *Health) OpenMonitorChannel() chan struct{} {
    58  	s.mu.Lock()
    59  	defer s.mu.Unlock()
    60  
    61  	if s.stop == nil {
    62  		logrus.Debug("OpenMonitorChannel")
    63  		s.stop = make(chan struct{})
    64  		return s.stop
    65  	}
    66  	return nil
    67  }
    68  
    69  // CloseMonitorChannel closes any existing monitor channel.
    70  func (s *Health) CloseMonitorChannel() {
    71  	s.mu.Lock()
    72  	defer s.mu.Unlock()
    73  
    74  	if s.stop != nil {
    75  		logrus.Debug("CloseMonitorChannel: waiting for probe to stop")
    76  		close(s.stop)
    77  		s.stop = nil
    78  		// unhealthy when the monitor has stopped for compatibility reasons
    79  		s.Health.Status = types.Unhealthy
    80  		logrus.Debug("CloseMonitorChannel done")
    81  	}
    82  }