Skip to content

Missed runs

What becomes of an occurrence that fell during a Runjet outage — once at startup, from a chosen reference point, and with a bounded wait for the agent.

Runjet is a process, and a process is sometimes not running: a deployment, a restart, an outage. What becomes of a tick that fell during one is decided by the Catch up missed runs switch on the job.

Off: the occurrence is dropped

The default. A tick that did not happen did not happen; the job runs again at the next scheduled time. For a five-minute health check or an hourly sync that is right — catching up past occurrences would mean nothing and interest nobody.

On: once at startup

When Runjet finds at startup that a job should have run since the reference point (below) and did not, it runs it once — whether it missed one occurrence or a hundred and twenty. So a two-hour outage never unleashes a hundred and twenty runs of a minutely job back to back. Such a run carries the catchup trigger with a history icon, so it can be told apart from the scheduled ones.

Switch it on for a job where a missing occurrence costs something: a nightly backup, monthly invoicing, a report somebody is waiting for. There, one run at startup is better than none — and the run's creation time says which occurrence it was.

What it is measured from

Runjet looks for occurrences since the latest of three points:

  • the job's last automatic run — a cron tick or an earlier catch-up. A manual run is deliberately not counted: Run now at noon must not cancel a nightly occurrence missed at three,
  • the job's creation, so a job that has never run does not catch up every occurrence since the beginning of time,
  • the floor written when the workspace was resumed — see below.

It is one rule in one query, not three reads and a maximum; which is why it cannot fall out of step with itself.

The wait for an agent is bounded

A caught-up run is a run like any other: it is created pending and waits for an agent to take it. If the agent is away, it waits — and while it does it holds its job's only slot on that agent, so until it is taken the job cannot run there at all. Without a deadline, an agent switched off for a week would mean a job that does not run for a week and then executes the occurrence from the day the agent left. A job that has quietly stopped running is exactly the failure this product exists to prevent, and that is worth more than a rescued occurrence.

So the deadline is:

  • one minute for a job without catch-up — past it the run ends as skipped and the job waits for the next tick,
  • 24 hours for a job with it. More precisely: the run time limit from the plan — and because no plan today puts a time limit on a run, those 24 hours are what actually applies, as a backstop, so that "runs are not timed out here" cannot quietly also mean "and their queue never drains".

Resuming a workspace is not restarting

A workspace suspended on day 30 and paid for on day 50 looks, to every job with catch-up, exactly like a twenty-day outage. So on resuming, Runjet writes a floor of "now" into every job in the workspace and catching up starts from there: nothing that should have run during the suspension runs after the payment. An ordinary restart of Runjet does not move that floor — that is the whole difference between an outage that should be caught up and a suspension that should not.