AshWorkflow.Verifiers.ValidateTimeoutPrecision (AshWorkflow v0.8.0)

Copy Markdown View Source

Rejects timeouts and every entities whose deadline is shorter than the selected scheduler can honour.

The floor comes from the scheduler, through AshWorkflow.Scheduler.precision_floor_ms/1. AshWorkflow.Scheduler.Oban polls on a cron interval, and cron's finest granularity is one minute — Oban.Cron zeroes the seconds field and its scheduler only wakes on minute boundaries — so a deadline shorter than a minute cannot be honoured there. fire_after: {30, :seconds} compiles happily and then fires anywhere up to 60 seconds late, an error larger than the deadline itself. The same is true of an every's interval.

Rather than let the DSL make a promise the scheduler cannot keep, a deadline under the floor is a compile error unless the entity sets self_scheduled?: true, which asserts that something other than the scheduler drives the trigger at the resolution the deadline needs.

AshWorkflow.Scheduler.Precise arms a timer per deadline, so its floor is a millisecond and a sub-minute deadline needs no flag.

A fire_at timeout is skipped

This check reads the duration an entity declares, fire_after on a timeout or interval on an every, and a fire_at timeout declares neither. It makes no duration promise: it says "once this instant has passed", and the polling interval decides how soon after. There is no promised precision to compare against the floor, so there is nothing to reject.

Before fire_at existed, the same outcome was reached by writing fire_after: {1, :seconds} against a field holding the deadline instant. That sentinel handed this verifier a number that meant nothing, and the verifier checked it anyway. fire_at says the thing directly, and skipping it is correct by construction.