{-# LANGUAGE ScopedTypeVariables, PatternGuards #-} {-# OPTIONS -fno-warn-orphans #-} -- | A simple ''cron'' loop. Used for running commands according to a given schedule. module BuildBox.Control.Cron ( module BuildBox.Data.Schedule , cronLoop ) where import BuildBox.Build import BuildBox.Data.Schedule import BuildBox.Command.Sleep import Data.Time -- | Given a schedule of commands, run them when their time is due. -- Only one command is run at a time. If several commands could be started at a specific -- moment, then we take the one with the earliest potential start time. If any command throws -- an error in the `Build` monad then the whole loop does. -- cronLoop :: Schedule (Build ())-> Build () cronLoop schedule = do startTime <- io $ getCurrentTime case earliestEventToStartAt startTime $ eventsOfSchedule schedule of Nothing -> do sleep 1 cronLoop schedule Just event -> do let Just build = lookupCommandOfSchedule (eventName event) schedule build endTime <- io $ getCurrentTime let event' = event { eventLastStarted = Just startTime , eventLastEnded = Just endTime } let schedule' = adjustEventOfSchedule event' schedule cronLoop schedule'