Files
mesh-catalog/modules/mesh-mail-reader/cmd/mesh-mail-reader/health.go
T

50 lines
2.2 KiB
Go

package main
// mesh-mail-reader's own health (novox/hq ADR 0459 §12, issue 1519): a tool the module's runtime-health of
// kind tool asks (mesh-vault's own pattern, module.json:68-75, novox/hq ADR 0366 §2 — a one-process module may
// judge itself by its own tool; the context file for this milestone says mesh-mail-notifier's health.go STOP
// comment, which says otherwise, is out of date). Unhealthy once a batch judgement is refused, times out or
// answers out of shape, naming which of the three, the judgement's own words, and since when (the first
// failure's own time, local); healthy again once a judgement succeeds. The state survives a restart: it is
// kept in the module's own database (store.go, pgstore.go), not only in memory.
import (
"fmt"
"time"
"git.novox.be/novox/mesh-sdk/go/health"
)
// HealthTool is the module's own health tool (the manifest's runtime-health, and one of its seven tools).
const HealthTool = "mail_reader_health"
// RecordJudgement folds one batch judgement's outcome into the kept health state (1519/AC2, AC3): a refused,
// timed-out or out-of-shape judgement makes it unhealthy, naming the cause and the judgement's own words, and
// keeps the FIRST failure's own since — a second, third, ... failure in a row never pushes since forward. A
// judgement that succeeds makes it healthy again at once.
func RecordJudgement(current ReaderHealth, outcome HealthOutcome, why string, now time.Time) ReaderHealth {
if outcome == OutcomeOK {
return ReaderHealth{Healthy: true}
}
since := now
if !current.Healthy && !current.Since.IsZero() {
since = current.Since
}
return ReaderHealth{Healthy: false, Cause: outcome, Why: why, Since: since}
}
// Answer is the state as mail_reader_health answers it (1519/AC2, AC3): unhealthy names which of the three
// outcomes, the judgement's own words, and since when, in local; healthy otherwise.
func (h ReaderHealth) Answer(local *time.Location) health.Answer {
if h.Healthy {
return health.Healthy("the last batch judgement succeeded")
}
since := h.Since
if local != nil {
since = since.In(local)
} else {
since = since.Local()
}
return health.Unhealthy(fmt.Sprintf("a batch judgement was %s: %s (since %s)", h.Cause, h.Why, since.Format("15:04 2006-01-02")))
}