status.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package probing
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. var (
  7. // weight factor
  8. α = 0.125
  9. )
  10. type Status interface {
  11. Total() int64
  12. Loss() int64
  13. Health() bool
  14. Err() error
  15. // Estimated smoothed round trip time
  16. SRTT() time.Duration
  17. // Estimated clock difference
  18. ClockDiff() time.Duration
  19. StopNotify() <-chan struct{}
  20. }
  21. type status struct {
  22. mu sync.Mutex
  23. srtt time.Duration
  24. total int64
  25. loss int64
  26. health bool
  27. err error
  28. clockdiff time.Duration
  29. stopC chan struct{}
  30. }
  31. // SRTT = (1-α) * SRTT + α * RTT
  32. func (s *status) SRTT() time.Duration {
  33. s.mu.Lock()
  34. defer s.mu.Unlock()
  35. return s.srtt
  36. }
  37. func (s *status) Total() int64 {
  38. s.mu.Lock()
  39. defer s.mu.Unlock()
  40. return s.total
  41. }
  42. func (s *status) Loss() int64 {
  43. s.mu.Lock()
  44. defer s.mu.Unlock()
  45. return s.loss
  46. }
  47. func (s *status) Health() bool {
  48. s.mu.Lock()
  49. defer s.mu.Unlock()
  50. return s.health
  51. }
  52. func (s *status) Err() error {
  53. s.mu.Lock()
  54. defer s.mu.Unlock()
  55. return s.err
  56. }
  57. func (s *status) ClockDiff() time.Duration {
  58. s.mu.Lock()
  59. defer s.mu.Unlock()
  60. return s.clockdiff
  61. }
  62. func (s *status) StopNotify() <-chan struct{} {
  63. return s.stopC
  64. }
  65. func (s *status) record(rtt time.Duration, when time.Time) {
  66. s.mu.Lock()
  67. defer s.mu.Unlock()
  68. s.total += 1
  69. s.health = true
  70. s.srtt = time.Duration((1-α)*float64(s.srtt) + α*float64(rtt))
  71. s.clockdiff = time.Now().Sub(when) - s.srtt/2
  72. s.err = nil
  73. }
  74. func (s *status) recordFailure(err error) {
  75. s.mu.Lock()
  76. defer s.mu.Unlock()
  77. s.total++
  78. s.health = false
  79. s.loss += 1
  80. s.err = err
  81. }
  82. func (s *status) reset() {
  83. s.mu.Lock()
  84. defer s.mu.Unlock()
  85. s.srtt = 0
  86. s.total = 0
  87. s.loss = 0
  88. s.health = false
  89. s.clockdiff = 0
  90. s.err = nil
  91. }