{-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeSynonymInstances #-} module Yam.Job( YamJob(..) , MonadJob(..) , startJob ) where import Yam.App import System.Cron data YamJob = YamJob { name :: Text , cron :: Text , func :: AppM IO () } class MonadIO m => MonadJob m where yamJobs :: m [(ThreadId, YamJob)] registerJob :: YamJob -> m () killJobs :: m () keyJob :: Text keyJob = "Extension.Job" instance (MonadIO m, MonadThrow m) => MonadJob (AppM m) where yamJobs = getExtensionOrDefault [] keyJob killJobs = yamJobs >>= mapM_ go >> setExtension keyJob ([] :: [(ThreadId, YamJob)]) where go (tid,job) = do infoLn $ "Stop job " <> name (job :: YamJob) <> "..." liftIO $ killThread tid registerJob job = do let nm = name (job :: YamJob) infoLn $ "Register job " <> nm <> " with cron '" <> cron job <> "'" context <- ask [thread] <- liftIO $ execSchedule $ flip addJob (cron job) $ do reqId <- randomHex 8 runAppM context $ withLoggerName (reqId <> " job." <> nm) $ do infoLn $ "Start job " <> nm func job infoLn $ "End job " <> nm jobs <- yamJobs setExtension keyJob ((thread,job):jobs) startJob :: [YamJob] -> (YamContext -> IO YamContext) -> IO () startJob jobs initialize = do context <- defaultContext >>= initialize runAppM context $ mapM_ registerJob jobs