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"))) }