github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/peer/metrics.go (about) 1 package peer 2 3 import ( 4 "sync" 5 "time" 6 ) 7 8 // LatencyEWMASmooting governs the decay of the EWMA (the speed 9 // at which it changes). This must be a normalized (0-1) value. 10 // 1 is 100% change, 0 is no change. 11 var LatencyEWMASmoothing = 0.1 12 13 // Metrics is just an object that tracks metrics 14 // across a set of peers. 15 type Metrics interface { 16 17 // RecordLatency records a new latency measurement 18 RecordLatency(ID, time.Duration) 19 20 // LatencyEWMA returns an exponentially-weighted moving avg. 21 // of all measurements of a peer's latency. 22 LatencyEWMA(ID) time.Duration 23 } 24 25 type metrics struct { 26 latmap map[ID]time.Duration 27 latmu sync.RWMutex 28 } 29 30 func NewMetrics() Metrics { 31 return &metrics{ 32 latmap: make(map[ID]time.Duration), 33 } 34 } 35 36 // RecordLatency records a new latency measurement 37 func (m *metrics) RecordLatency(p ID, next time.Duration) { 38 nextf := float64(next) 39 s := LatencyEWMASmoothing 40 if s > 1 || s < 0 { 41 s = 0.1 // ignore the knob. it's broken. look, it jiggles. 42 } 43 44 m.latmu.Lock() 45 ewma, found := m.latmap[p] 46 ewmaf := float64(ewma) 47 if !found { 48 m.latmap[p] = next // when no data, just take it as the mean. 49 } else { 50 nextf = ((1.0 - s) * ewmaf) + (s * nextf) 51 m.latmap[p] = time.Duration(nextf) 52 } 53 m.latmu.Unlock() 54 } 55 56 // LatencyEWMA returns an exponentially-weighted moving avg. 57 // of all measurements of a peer's latency. 58 func (m *metrics) LatencyEWMA(p ID) time.Duration { 59 m.latmu.RLock() 60 lat := m.latmap[p] 61 m.latmu.RUnlock() 62 return time.Duration(lat) 63 }