diff --git a/.gitignore b/.gitignore index fdeda75..f556e37 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ request-log +webcheck diff --git a/main.go b/main.go index 68f9efb..ea62e1b 100644 --- a/main.go +++ b/main.go @@ -19,7 +19,10 @@ import ( log "github.com/sirupsen/logrus" ) -const dateFormat = time.RFC1123 +const ( + dateFormat = time.RFC1123 + numHistoricalDurations = 300 +) var ( cfg = struct { @@ -54,7 +57,7 @@ const ( type checkResult struct { DumpFile string - Durations []time.Duration + Durations *ringDuration Message string Start time.Time Status checkStatus @@ -64,8 +67,11 @@ type checkResult struct { } func newCheckResult(status checkStatus, message string, duration time.Duration) *checkResult { + r := newRingDuration(numHistoricalDurations) + r.SetNext(duration) + return &checkResult{ - Durations: []time.Duration{duration}, + Durations: r, Message: message, Start: time.Now(), Status: status, @@ -76,7 +82,7 @@ func (c *checkResult) AddDuration(d time.Duration) { c.lock.Lock() defer c.lock.Unlock() - c.Durations = append(c.Durations, d) + c.Durations.SetNext(d) } func (c *checkResult) DurationStats() string { @@ -84,7 +90,7 @@ func (c *checkResult) DurationStats() string { defer c.lock.RUnlock() var ( - s = stats.LoadRawData(c.Durations) + s = stats.LoadRawData(c.Durations.GetAll()) min, avg, max float64 err error ) @@ -176,7 +182,7 @@ func main() { lastResult.DumpFile = fn } } else { - lastResult.AddDuration(result.Durations[0]) + lastResult.AddDuration(result.Durations.GetCurrent()) } lastResult.Print() diff --git a/ring.go b/ring.go new file mode 100644 index 0000000..fa51a02 --- /dev/null +++ b/ring.go @@ -0,0 +1,51 @@ +package main + +import ( + "sync" + "time" +) + +type ringDuration struct { + store []time.Duration + current int + + lock sync.RWMutex +} + +func newRingDuration(maxLen int) *ringDuration { + return &ringDuration{ + store: make([]time.Duration, 0, maxLen), + current: -1, // Initial value to start the ring with element 0 + } +} + +func (r *ringDuration) SetNext(i time.Duration) { + r.lock.Lock() + defer r.lock.Unlock() + + next := r.current + 1 + if next == cap(r.store) { + next = 0 + } + + if next == len(r.store) { + r.store = append(r.store, 0) + } + + r.store[next] = i + r.current = next +} + +func (r *ringDuration) GetAll() []time.Duration { + r.lock.RLock() + defer r.lock.RUnlock() + + return r.store +} + +func (r *ringDuration) GetCurrent() time.Duration { + r.lock.RLock() + defer r.lock.RUnlock() + + return r.store[r.current] +}