...

Source file src/github.com/xiang90/probing/status.go

Documentation: github.com/xiang90/probing

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

View as plain text