module Network.AWS.Loup.Decide
( deciding
, decide
, decideMain
) where
import Control.Monad.Trans.AWS
import Data.UUID
import Data.UUID.V4
import Data.Yaml
import Network.AWS.Loup.Ctx
import Network.AWS.Loup.Prelude
import Network.AWS.Loup.Types
import Network.AWS.SWF
pollDecision :: MonadStatsCtx c m => Text -> TaskList -> m (Maybe Text, [HistoryEvent])
pollDecision domain list =
runResourceT $ runAmazonCtx $ do
pfdtrs <- pages $ pollForDecisionTask domain list
return (join $ headMay $ view pfdtrsTaskToken <$> pfdtrs, reverse $ join $ view pfdtrsEvents <$> pfdtrs)
completeDecision :: MonadStatsCtx c m => Text -> [Decision] -> m ()
completeDecision token decisions =
runResourceT $ runAmazonCtx $
void $ send $ respondDecisionTaskCompleted token
& rdtcDecisions .~ decisions
scheduleActivity :: UUID -> ActivityType -> TaskList -> Maybe Text -> Decision
scheduleActivity uid activity list input = do
let satda = scheduleActivityTaskDecisionAttributes activity (toText uid)
& satdaTaskList .~ return list
& satdaInput .~ input
decision ScheduleActivityTask
& dScheduleActivityTaskDecisionAttributes .~ return satda
completeActivity :: Decision
completeActivity = do
let cweda = completeWorkflowExecutionDecisionAttributes
decision CompleteWorkflowExecution
& dCompleteWorkflowExecutionDecisionAttributes .~ return cweda
cancelActivity :: Decision
cancelActivity = do
let cweda = cancelWorkflowExecutionDecisionAttributes
decision CancelWorkflowExecution
& dCancelWorkflowExecutionDecisionAttributes .~ return cweda
requestCancel :: UUID -> Decision
requestCancel uid = do
let rcatda = requestCancelActivityTaskDecisionAttributes (toText uid)
decision RequestCancelActivityTask
& dRequestCancelActivityTaskDecisionAttributes .~ return rcatda
findEvent :: MonadDecisionCtx c m => EventType -> m (Maybe HistoryEvent)
findEvent eventType = do
let f [] = return Nothing
f (e:es) = bool (f es) (return $ Just e) $ e ^. heEventType == eventType
events <- view dcEvents
f events
begin :: MonadDecisionCtx c m => HistoryEvent -> m [Decision]
begin event = do
traceInfo "begin" mempty
uid <- liftIO nextRandom
task <- view pActivityTask <$> view dcPlan
let input = join $ view weseaInput <$> event ^. heWorkflowExecutionStartedEventAttributes
return [ scheduleActivity uid (task ^. tActivityType) (task ^. tTaskList) input ]
cancel :: MonadDecisionCtx c m => m [Decision]
cancel = do
traceInfo "cancel" mempty
event <- findEvent ActivityTaskScheduled
let uid = join $ fromText . view atseaActivityId <$> join (view heActivityTaskScheduledEventAttributes <$> event)
return [ maybe cancelActivity requestCancel uid ]
completed :: MonadDecisionCtx c m => m [Decision]
completed = do
traceInfo "completed" mempty
return [ completeActivity ]
restart :: MonadDecisionCtx c m => m [Decision]
restart = do
traceInfo "restart" mempty
uid <- liftIO nextRandom
task <- view pActivityTask <$> view dcPlan
event <- findEvent WorkflowExecutionStarted
let input = join $ view weseaInput <$> join (view heWorkflowExecutionStartedEventAttributes <$> event)
return [ scheduleActivity uid (task ^. tActivityType) (task ^. tTaskList) input ]
canceled :: MonadDecisionCtx c m => m [Decision]
canceled = do
traceInfo "canceled" mempty
return [ cancelActivity ]
nothing :: MonadDecisionCtx c m => m [Decision]
nothing = do
events <- view dcEvents
traceError "none" [ "events" .= (textShow . view heEventType <$> events) ]
return mempty
schedule :: MonadDecisionCtx c m => m [Decision]
schedule = do
traceInfo "schedule" mempty
let f [] = nothing
f (e:es)
| e ^. heEventType == WorkflowExecutionStarted = begin e
| e ^. heEventType == WorkflowExecutionCancelRequested = cancel
| e ^. heEventType == ActivityTaskCompleted = completed
| e ^. heEventType == ActivityTaskCanceled = completed
| e ^. heEventType == ActivityTaskTimedOut = restart
| e ^. heEventType == ActivityTaskFailed = restart
| e ^. heEventType == RequestCancelActivityTaskFailed = canceled
| otherwise = f es
events <- view dcEvents
f events
deciding :: MonadStatsCtx c m => Text -> Plan -> m ()
deciding domain plan = do
traceInfo "poll" mempty
(token, events) <- pollDecision domain (plan ^. pDecisionTask ^. tTaskList)
maybe_ token $ \token' -> do
traceInfo "start" mempty
runDecisionCtx plan events $ do
decisions <- schedule
completeDecision token' decisions
traceInfo "finish" mempty
decide :: MonadStatsCtx c m => Text -> Plan -> m ()
decide domain plan =
preStatsCtx [ "label" .= LabelDecide, "domain" .= domain ] $
deciding domain plan
decideMain :: MonadControl m => Text -> FilePath -> m ()
decideMain domain file =
runCtx $ runStatsCtx $ do
plans <- liftIO $ join . maybeToList <$> decodeFile file
runConcurrent $ forever . decide domain <$> plans