github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/utils/rate/gauge.go (about) 1 package rate 2 3 import ( 4 "sync/atomic" 5 6 "github.com/unicornultrafoundation/go-u2u/metrics" 7 ) 8 9 // Gauge represents an exponentially-weighted moving average of given values 10 type Gauge struct { 11 input metrics.Meter 12 count metrics.Meter 13 max int64 14 } 15 16 // NewGauge constructs a new Gauge and launches a goroutine. 17 // Be sure to call Stop() once the meter is of no use to allow for garbage collection. 18 func NewGauge() *Gauge { 19 return &Gauge{ 20 input: metrics.NewMeterForced(), 21 count: metrics.NewMeterForced(), 22 } 23 } 24 25 // Mark records the the current value of the gauge. 26 func (g *Gauge) Mark(v int64) { 27 g.input.Mark(v) 28 g.count.Mark(1) 29 //// maintain maximum input value in a thread-safe way 30 for max := g.getMax(); max < v && !atomic.CompareAndSwapInt64(&g.max, max, v); { 31 max = g.getMax() 32 } 33 } 34 35 func (g *Gauge) getMax() int64 { 36 return atomic.LoadInt64(&g.max) 37 } 38 39 func (g *Gauge) rateToGauge(valuesSum, calls float64) float64 { 40 if calls < 0.000001 { 41 return 0 42 } 43 gaugeValue := valuesSum / calls 44 // gaugeValue cannot be larger than a maximum input value 45 max := float64(g.getMax()) 46 if gaugeValue > max { 47 return max 48 } 49 return gaugeValue 50 } 51 52 // Rate1 returns the one-minute moving average of the gauge values. 53 // Cannot be larger than max(largest input value, 0) 54 func (g *Gauge) Rate1() float64 { 55 return g.rateToGauge(g.input.Rate1(), g.count.Rate1()) 56 } 57 58 // Rate5 returns the five-minute moving average of the gauge values. 59 // Cannot be larger than max(largest input value, 0) 60 func (g *Gauge) Rate5() float64 { 61 return g.rateToGauge(g.input.Rate5(), g.count.Rate5()) 62 } 63 64 // Rate15 returns the fifteen-minute moving average of the gauge values. 65 // Cannot be larger than max(largest input value, 0) 66 func (g *Gauge) Rate15() float64 { 67 return g.rateToGauge(g.input.Rate15(), g.count.Rate15()) 68 } 69 70 // RateMean returns the gauge's mean value. 71 // Cannot be larger than max(largest input value, 0) 72 func (g *Gauge) RateMean() float64 { 73 return g.rateToGauge(g.input.RateMean(), g.count.RateMean()) 74 } 75 76 // Stop stops the gauge 77 func (g *Gauge) Stop() { 78 g.input.Stop() 79 g.count.Stop() 80 }