Functional Weave
Code in TypeScript

monitor.heartbeat@1.0.0

README.md

2,099 bytes · view raw

# monitor.heartbeat

The state of a heartbeat check (a "dead man's switch"): a cron job, backup or
worker pings the monitor each time it runs, and the monitor raises the alarm
when the pings stop. This is the shape healthchecks.io, Cronitor and
Uptime Kuma's push monitors use, with healthchecks.io's vocabulary:

| state | healthchecks.io says | here |
| --- | --- | --- |
| `new` | "A newly created check that has not received any pings yet." | `lastPingAt` is null |
| `up` | "The last success signal has arrived on time." | `now <= dueAt` |
| `late` | "The success signal is due but has not arrived yet. It is not yet late by more than the check's configured Grace Time." | `dueAt < now <= downAt` |
| `down` | "The success signal has not arrived yet, and the Grace Time has elapsed." | `now > downAt` |

where `dueAt = lastPingAt + intervalSeconds` and
`downAt = dueAt + graceSeconds`. The due second itself is still up, and the
last second of the grace time is still late; the state changes the second
after. With no grace time a check goes straight from up to down.

`overdueSeconds` is `now - dueAt` when late or down (how long past due, for
"late by 2m" in an alert), and 0 otherwise. `dueAt` and `downAt` are returned
so the caller can schedule its next evaluation instead of polling.

## Edge cases

- A ping stamped after `now` (the job's clock is ahead of the monitor's) is
  `up`, overdue 0: its due time is later still. It is not an error, because
  clock skew is normal and refusing it would hide a healthy job.
- `paused` is not a state here: pausing is the caller's decision, not
  something the ping times say.
- Only simple period schedules are covered; a cron-expression schedule gives
  `dueAt` from the expression instead.

## Errors

- `intervalSeconds must be at least 1, received X`
- `graceSeconds must not be negative, received X`
- `NAME must be whole seconds, received X` for a fractional time

## Sources

- healthchecks.io documentation, "Check states" and "Period and Grace Time":
  https://healthchecks.io/docs/ and https://healthchecks.io/docs/configuring_checks/