module Job.Daemon ( runDaemons ) where import Data.Time.Clock (UTCTime) import Control.Concurrent (threadDelay, forkIO, ThreadId) import Control.Monad (forever) import Model.Database import Job.Kind (Kind(..)) import Job.Frequency (Frequency(..), microSeconds) import Job.Model (getLastExecution, actualizeLastCheck, actualizeLastExecution) import Job.MonthlyPayment (monthlyPayment) import Job.WeeklyReport (weeklyReport) import Conf (Conf) import Utils.Time (belongToCurrentMonth, belongToCurrentWeek) runDaemons :: Conf -> IO () runDaemons conf = do _ <- runDaemon MonthlyPayment EveryHour (fmap not . belongToCurrentMonth) monthlyPayment _ <- runDaemon WeeklyReport EveryHour (fmap not . belongToCurrentWeek) (weeklyReport conf) return () runDaemon :: Kind -> Frequency -> (UTCTime -> IO Bool) -> (Maybe UTCTime -> IO UTCTime) -> IO ThreadId runDaemon kind frequency isLastExecutionTooOld runJob = forkIO . forever $ do mbLastExecution <- runDb $ do actualizeLastCheck kind getLastExecution kind hasToRun <- case mbLastExecution of Just lastExecution -> isLastExecutionTooOld lastExecution Nothing -> return True if hasToRun then runJob mbLastExecution >>= (runDb . actualizeLastExecution kind) else return () threadDelay . microSeconds $ frequency