| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
Arbiter.Worker.Cron
Description
Cron scheduler for the Arbiter worker pool.
When cronJobs is non-empty in WorkerConfig, runWorkerPool spawns an
additional thread that inserts jobs based on 5-field cron expressions.
Uses IgnoreDuplicate dedup keys for multi-instance idempotency.
All cron expressions are evaluated in UTC. There is no local-timezone
support — "0 3 * * *" means 03:00 UTC, not 03:00 in the server's
local time. Account for your timezone offset when writing expressions.
When a connection pool and schema are provided, the scheduler consults the
cron_schedules table for runtime overrides (expression, overlap, enabled).
Synopsis
- data CronJob payload = CronJob {
- name :: Text
- cronExpression :: Text
- schedule :: CronSchedule
- overlap :: OverlapPolicy
- builder :: UTCTime -> JobWrite payload
- data OverlapPolicy
- cronJob :: Text -> Text -> OverlapPolicy -> (UTCTime -> JobWrite payload) -> Either String (CronJob payload)
- overlapPolicyToText :: OverlapPolicy -> Text
- overlapPolicyFromText :: Text -> Maybe OverlapPolicy
- initCronSchedules :: Connection -> Text -> [CronJob payload] -> LogConfig -> IO ()
- runCronScheduler :: forall m (registry :: JobPayloadRegistry) payload. (MonadUnliftIO m, QueueOperation m registry payload) => Connection -> LogConfig -> Text -> [CronJob payload] -> m ()
- processCronTick :: forall m (registry :: JobPayloadRegistry) payload. (MonadUnliftIO m, QueueOperation m registry payload) => Connection -> LogConfig -> Text -> [CronJob payload] -> UTCTime -> m ()
- truncateToMinute :: UTCTime -> UTCTime
- formatMinute :: UTCTime -> Text
- makeDedupKey :: CronJob payload -> UTCTime -> Text
- computeDelayMicros :: UTCTime -> Int
Types
A cron schedule definition.
Use cronJob to construct — it parses the cron expression eagerly,
so invalid expressions are caught at construction time.
Constructors
| CronJob | |
Fields
| |
Instances
data OverlapPolicy Source #
Determines how overlapping cron ticks are deduplicated.
Constructors
| SkipOverlap | At most one pending or running job per schedule name. |
| AllowOverlap | One job per tick. Allows concurrent execution of prior ticks. |
Instances
| Generic OverlapPolicy Source # | |||||
Defined in Arbiter.Worker.Cron Associated Types
| |||||
| Show OverlapPolicy Source # | |||||
Defined in Arbiter.Worker.Cron Methods showsPrec :: Int -> OverlapPolicy -> ShowS # show :: OverlapPolicy -> String # showList :: [OverlapPolicy] -> ShowS # | |||||
| Eq OverlapPolicy Source # | |||||
Defined in Arbiter.Worker.Cron Methods (==) :: OverlapPolicy -> OverlapPolicy -> Bool # (/=) :: OverlapPolicy -> OverlapPolicy -> Bool # | |||||
| type Rep OverlapPolicy Source # | |||||
Smart Constructor
Arguments
| :: Text | Schedule name (used in dedup keys and logging) |
| -> Text | Cron expression (5-field: minute hour day-of-month month day-of-week) |
| -> OverlapPolicy | |
| -> (UTCTime -> JobWrite payload) | |
| -> Either String (CronJob payload) |
Smart constructor for CronJob. Parses the cron expression eagerly.
Returns Left with an error message if the cron expression is invalid.
Note: cron expressions are evaluated in UTC. "0 3 * * *" fires at
03:00 UTC regardless of the server's local timezone.
Example:
cronJob "nightly-report" "0 3 * * *" SkipOverlap (\_ -> defaultJob (GenerateReport "nightly"))
Helpers
overlapPolicyToText :: OverlapPolicy -> Text Source #
Convert an OverlapPolicy to its text representation.
overlapPolicyFromText :: Text -> Maybe OverlapPolicy Source #
Parse an OverlapPolicy from text.
DB Init
initCronSchedules :: Connection -> Text -> [CronJob payload] -> LogConfig -> IO () Source #
Initialize the cron_schedules table and upsert defaults for all cron jobs.
Called once at scheduler startup. Upserts default_expression and
default_overlap for each CronJob, preserving any user overrides and
enabled state.
Internal
runCronScheduler :: forall m (registry :: JobPayloadRegistry) payload. (MonadUnliftIO m, QueueOperation m registry payload) => Connection -> LogConfig -> Text -> [CronJob payload] -> m () Source #
Run the cron scheduler loop. Called by runWorkerPool when cronJobs
is non-empty.
On each minute boundary, checks all schedules and inserts matching jobs with appropriate dedup keys. Exceptions per-schedule are caught and logged; the loop continues.
The provided Connection is used to consult the cron_schedules table
for effective expression, overlap, and enabled state on each tick.
processCronTick :: forall m (registry :: JobPayloadRegistry) payload. (MonadUnliftIO m, QueueOperation m registry payload) => Connection -> LogConfig -> Text -> [CronJob payload] -> UTCTime -> m () Source #
Process a single cron tick at the given time.
For each CronJob, consults the DB for effective expression, overlap, and enabled.
If the schedule is disabled, it is skipped. If the effective expression fails to parse,
it is logged and skipped.
truncateToMinute :: UTCTime -> UTCTime Source #
Truncate a UTCTime to the current minute (zero out seconds).
makeDedupKey :: CronJob payload -> UTCTime -> Text Source #
Compute the dedup key for a cron job at the given tick time.
Uses the code-defined overlap policy. If the schedule has a DB override,
use makeDedupKeyFromParts with the effective policy instead.
computeDelayMicros :: UTCTime -> Int Source #
Compute the delay in microseconds until the next minute boundary,
clamped to [0, 120_000_000].