health.go 1.8 KB

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