...
1 package probing
2
3 import (
4 "sync"
5 "time"
6 )
7
8 var (
9
10 α = 0.125
11 )
12
13 type Status interface {
14 Total() int64
15 Loss() int64
16 Health() bool
17 Err() error
18
19 SRTT() time.Duration
20
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
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