#93: Gracefully handle breaking change to uptime maps by renaming variables

This commit is contained in:
TwinProduction 2021-03-06 15:19:35 -05:00
parent 076b92a2b4
commit f945e4b8a2
2 changed files with 22 additions and 16 deletions

View File

@ -20,39 +20,45 @@ type Uptime struct {
// LastHour is the uptime percentage over the past hour // LastHour is the uptime percentage over the past hour
LastHour float64 `json:"1h"` LastHour float64 `json:"1h"`
// SuccessCountPerHour is a map containing the number of successes (value) for every hourly unix timestamps (key) // SuccessfulExecutionsPerHour is a map containing the number of successes (value)
SuccessCountPerHour map[int64]uint64 `json:"-"` // for every hourly unix timestamps (key)
SuccessfulExecutionsPerHour map[int64]uint64 `json:"-"`
// TotalCountPerHour is a map containing the total number of checks (value) for every hourly unix timestamps (key) // TotalExecutionsPerHour is a map containing the total number of checks (value)
TotalCountPerHour map[int64]uint64 `json:"-"` // for every hourly unix timestamps (key)
TotalExecutionsPerHour map[int64]uint64 `json:"-"`
} }
// NewUptime creates a new Uptime // NewUptime creates a new Uptime
func NewUptime() *Uptime { func NewUptime() *Uptime {
return &Uptime{ return &Uptime{
SuccessCountPerHour: make(map[int64]uint64), SuccessfulExecutionsPerHour: make(map[int64]uint64),
TotalCountPerHour: make(map[int64]uint64), TotalExecutionsPerHour: make(map[int64]uint64),
} }
} }
// ProcessResult processes the result by extracting the relevant from the result and recalculating the uptime // ProcessResult processes the result by extracting the relevant from the result and recalculating the uptime
// if necessary // if necessary
func (uptime *Uptime) ProcessResult(result *Result) { func (uptime *Uptime) ProcessResult(result *Result) {
if uptime.SuccessfulExecutionsPerHour == nil || uptime.TotalExecutionsPerHour == nil {
uptime.SuccessfulExecutionsPerHour = make(map[int64]uint64)
uptime.TotalExecutionsPerHour = make(map[int64]uint64)
}
unixTimestampFlooredAtHour := result.Timestamp.Unix() - (result.Timestamp.Unix() % 3600) unixTimestampFlooredAtHour := result.Timestamp.Unix() - (result.Timestamp.Unix() % 3600)
if result.Success { if result.Success {
uptime.SuccessCountPerHour[unixTimestampFlooredAtHour]++ uptime.SuccessfulExecutionsPerHour[unixTimestampFlooredAtHour]++
} }
uptime.TotalCountPerHour[unixTimestampFlooredAtHour]++ uptime.TotalExecutionsPerHour[unixTimestampFlooredAtHour]++
// Clean up only when we're starting to have too many useless keys // Clean up only when we're starting to have too many useless keys
// Note that this is only triggered when there are more entries than there should be after // Note that this is only triggered when there are more entries than there should be after
// 10 days, despite the fact that we are deleting everything that's older than 7 days. // 10 days, despite the fact that we are deleting everything that's older than 7 days.
// This is to prevent re-iterating on every `ProcessResult` as soon as the uptime has been logged for 7 days. // This is to prevent re-iterating on every `ProcessResult` as soon as the uptime has been logged for 7 days.
if len(uptime.TotalCountPerHour) > numberOfHoursInTenDays { if len(uptime.TotalExecutionsPerHour) > numberOfHoursInTenDays {
sevenDaysAgo := time.Now().Add(-(sevenDays + time.Hour)).Unix() sevenDaysAgo := time.Now().Add(-(sevenDays + time.Hour)).Unix()
for hourlyUnixTimestamp := range uptime.TotalCountPerHour { for hourlyUnixTimestamp := range uptime.TotalExecutionsPerHour {
if sevenDaysAgo > hourlyUnixTimestamp { if sevenDaysAgo > hourlyUnixTimestamp {
delete(uptime.TotalCountPerHour, hourlyUnixTimestamp) delete(uptime.TotalExecutionsPerHour, hourlyUnixTimestamp)
delete(uptime.SuccessCountPerHour, hourlyUnixTimestamp) delete(uptime.SuccessfulExecutionsPerHour, hourlyUnixTimestamp)
} }
} }
} }
@ -80,8 +86,8 @@ func (uptime *Uptime) recalculate() {
timestamp := now.Add(-sevenDays) timestamp := now.Add(-sevenDays)
for now.Sub(timestamp) >= 0 { for now.Sub(timestamp) >= 0 {
hourlyUnixTimestamp := timestamp.Unix() - (timestamp.Unix() % 3600) hourlyUnixTimestamp := timestamp.Unix() - (timestamp.Unix() % 3600)
successCountForTimestamp := uptime.SuccessCountPerHour[hourlyUnixTimestamp] successCountForTimestamp := uptime.SuccessfulExecutionsPerHour[hourlyUnixTimestamp]
totalCountForTimestamp := uptime.TotalCountPerHour[hourlyUnixTimestamp] totalCountForTimestamp := uptime.TotalExecutionsPerHour[hourlyUnixTimestamp]
uptimeBrackets["7d_success"] += successCountForTimestamp uptimeBrackets["7d_success"] += successCountForTimestamp
uptimeBrackets["7d_total"] += totalCountForTimestamp uptimeBrackets["7d_total"] += totalCountForTimestamp
if now.Sub(timestamp) <= 24*time.Hour { if now.Sub(timestamp) <= 24*time.Hour {

View File

@ -51,8 +51,8 @@ func TestServiceStatus_AddResultUptimeIsCleaningUpAfterItself(t *testing.T) {
timestamp := now.Add(-12 * 24 * time.Hour) timestamp := now.Add(-12 * 24 * time.Hour)
for timestamp.Unix() <= now.Unix() { for timestamp.Unix() <= now.Unix() {
serviceStatus.AddResult(&Result{Timestamp: timestamp, Success: true}) serviceStatus.AddResult(&Result{Timestamp: timestamp, Success: true})
if len(serviceStatus.Uptime.SuccessCountPerHour) > numberOfHoursInTenDays { if len(serviceStatus.Uptime.SuccessfulExecutionsPerHour) > numberOfHoursInTenDays {
t.Errorf("At no point in time should there be more than %d entries in serviceStatus.SuccessCountPerHour, but there are %d", numberOfHoursInTenDays, len(serviceStatus.Uptime.SuccessCountPerHour)) t.Errorf("At no point in time should there be more than %d entries in serviceStatus.SuccessfulExecutionsPerHour, but there are %d", numberOfHoursInTenDays, len(serviceStatus.Uptime.SuccessfulExecutionsPerHour))
} }
if now.Sub(timestamp) > time.Hour && serviceStatus.Uptime.LastHour != 0 { if now.Sub(timestamp) > time.Hour && serviceStatus.Uptime.LastHour != 0 {
t.Error("most recent timestamp > 1h ago, expected serviceStatus.Uptime.LastHour to be 0, got", serviceStatus.Uptime.LastHour) t.Error("most recent timestamp > 1h ago, expected serviceStatus.Uptime.LastHour to be 0, got", serviceStatus.Uptime.LastHour)