Functional Weave
Code in Rust

monitor.heartbeat-check

A heartbeat's state as a check status for a status page: up, late as degraded, down as down, new as nothing yet.

1.0.0 · published 2026-10-03 by charlie · Anterra

Pinned by 8 tests, run in TypeScript, Python and Rust.

What it does

A heartbeat (a cron job that pings the monitor on a schedule, judged by `monitor.heartbeat`) as one check behind a status page component, so the job can sit on the same page as the HTTP targets and feed `monitor.component-state`, `monitor.incidents` and `monitor.uptime`.

| heartbeat state | check status | why | | --- | --- | --- | | `up` | `up` | pinged within its period | | `late` | `degraded` | past due but inside the grace time: something is slow, nothing has failed yet | | `down` | `down` | past the grace time: the job has stopped | | `new` | null | it has never pinged, so there is nothing to report |

For example

  • heartbeat_check(up) → up a heartbeat pinging on time is up
  • heartbeat_check(late) → degraded a late heartbeat is degraded, not down: it is still inside its grace time
  • heartbeat_check(down) → down a heartbeat past its grace time is down

The function

The same function in TypeScript, Python and Rust, pinned by the same tests. Pick your language; the choice follows you around the registry.

pub fn heartbeat_check(state: &str) -> Option<String>
stateHeartbeatStatewhere the heartbeat stands, from monitor.heartbeat
returnsCheckStatus?null for a heartbeat that has never pinged: there is nothing to report yet

Your code names it in one line, in the file that uses it

fune!(monitor.heartbeat-check@^1);  // then call heartbeat_check(…)
impl/rust.rs · 26 lines · open · raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one

/// A heartbeat as one check behind a status page component. Late is
/// degraded, not down: the job may still ping within its grace time, which is
/// what the grace time is for. A new heartbeat has proved nothing either way,
/// so it is None rather than a guess.
///
/// # Panics
/// Panics on an unknown state.
pub fn heartbeat_check(state: &str) -> Option<String> {
    match state {
        "new" => None,
        "up" => Some("up".to_string()),
        "late" => Some("degraded".to_string()),
        "down" => Some("down".to_string()),
        other => panic!("unknown heartbeat state: {}", other),
    }
}

pub fn fune_vector(args: &[Value]) -> Value {
    let state = args[0].as_str().to_string();
    match heartbeat_check(&state) {
        Some(s) => Value::str(&s),
        None => Value::Null,
    }
}

Install

fune build

With that line in your source, in a Rust project (language rust in fune.project), fune build resolves it and its 2 dependencies, pins them in fune.lock, downloads only the Rust package of each, and builds the code above into your project’s .fune/build, one readable file per capability with a header linking back here. A crate’s build.rs runs it before every compile. Or pin a range in fune.project and build in one step:

fune add monitor.heartbeat-check
Download for Rust monitor.heartbeat-check-1.0.0-rust.fune · 4,947 bytes sha256 0e88d36ebbc877686ae9d80caeae62f6be6ef43fd71632b5e5cd9cf96436e197

The manifest, vectors and README with only the Rust implementation. Install it without the registry with fune add ./monitor.heartbeat-check-1.0.0-rust.fune, or fetch it from a terminal with fune pull monitor.heartbeat-check@1.0.0:rust.

The whole function, every language, is one file too: monitor.heartbeat-check-1.0.0.fune, 6,589 bytes, sha256 ba92e30f23d19bb08606233144125bb805f847790f3973b11d15a465ee2381f9. It installs into a project of any language.

Customise it in your app

The seams this capability offers. Put a marker directly above a function of your own and fune build wires it into the built code; the package on the registry is not changed, the built file’s header lists it under CUSTOMISED, and fune hooks lists every hook in the project. How hooks work.

before — your function gets the arguments and returns them, changed or not, or throws to refuse the call.

// fune: before monitor.heartbeat-check

after — your function gets the result and the arguments, and returns the final result.

// fune: after monitor.heartbeat-check

replace — inside this capability’s code only, calls to a dependency go to your function, with the same signature. Other capabilities that use it are unaffected; write in * to replace it everywhere.

// fune: replace monitor.check-status in monitor.heartbeat-check
// fune: replace monitor.heartbeat in monitor.heartbeat-check

step — your function runs at a numbered point inside the function’s body, receives the in-scope values it names as parameters, and may return replacements. List the points with fune show monitor.heartbeat-check --steps.

// fune: step monitor.heartbeat-check after <n|label>

Tests

A version published now needs at least 8 tests for every function, and one that expects the error for each function that throws; the registry refuses it otherwise. fune verify --all runs each case in TypeScript, Python and Rust, and a project runs them again with fune verify. This page lists the cases; it does not run them. The exact JSON is vectors.json.

CaseArgumentsExpected
a heartbeat pinging on time is up up → up
a late heartbeat is degraded, not down: it is still inside its grace time late → degraded
a heartbeat past its grace time is down down → down
a heartbeat that has never pinged has nothing to report new → —
an unknown state is an error missing → error: unknown heartbeat state: missing
states are case-sensitive Up → error: unknown heartbeat state: Up
an empty state is an error → error: unknown heartbeat state:
a check status is not a heartbeat state: degraded is refused degraded → error: unknown heartbeat state: degraded

More from the author

## Why this shape

- **Late is not down.** The grace time exists because jobs run long; calling a late job down would page for exactly the case the grace time was set to absorb. healthchecks.io, which named these states, only alerts on down. - **New is null, not up.** A heartbeat that has never pinged has proved nothing. Calling it up would show a never-deployed job as healthy on the status page; calling it down would page for a job that is not due yet. The caller leaves it out of the component's checks (and shows "awaiting first ping") until the first ping arrives.

## Errors

- `unknown heartbeat state: X`, for anything but `new`, `up`, `late` and `down` (case-sensitive; a `CheckStatus` such as `degraded` is refused).

## Sources

- healthchecks.io, "Configuring checks: period and grace time" (new, up, late, down; notifications only when a check goes down): https://healthchecks.io/docs/configuring_checks/

Files

PathBytes
README.md1,600
impl/python.py719
impl/rust.rs845
impl/typescript.ts820
vectors.json877