-- | Atomically apply multiple actions.
atomicActs :: AppState -> Maybe Cluster -> [(UUID, Action)] -> Either AtomicFailure ES.TransitionaryState
atomicActs st0 cl as = invert . ES.runState st0 . runExceptT $ mapM_ (uncurry enact') as
  where
    invert (res, st') = either Left (const $ Right st') res
    enact' u a = withExceptT (AtomicFailure a) $ enact u a
    enact u (ActCreateJob spec) = createJob u cl spec
    enact _ (ActKillJob   name) = killJob name
    enact _ (ActPatchJob n pat) = patchDepends n pat
    enact _ (ActDeleteJob name) = deleteJob name
    enact _ (ActCreateBox spec) = createBox spec
    enact _ (ActSealBox   name) = sealBox name
    enact _ (ActDeleteBox name) = deleteBox name

-- Only check on active jobs; terminated jobs shouldn't change status
-- | All jobs that should be queried on the scheduler.
atomicActs :: AppState -> Maybe Cluster -> [(UUID, Action)] -> Either AtomicFailure ES.TransitionaryState
atomicActs st0 cl as = invert . ES.runState st0 . runExceptT $ mapM_ (uncurry enact') as
  where
    invert (res, st') = either Left (const $ Right st') res
    enact' u a = withExceptT (AtomicFailure a) $ enact u a
    enact u (ActCreateJob spec) = createJob u cl spec
    enact _ (ActKillJob   name) = killJob name
    enact _ (ActPatchJob n pat) = patchDepends n pat
    enact _ (ActDeleteJob name) = deleteJob name
    enact _ (ActCreateBox spec) = createBox spec
    enact _ (ActSealBox   name) = sealBox name
    enact _ (ActDeleteBox name) = deleteBox name

-- Only check on active jobs; terminated jobs shouldn't change status
-- | All jobs that should be queried on the scheduler.
atomicActs st0 cl as = invert . ES.runState st0 . runExceptT $ mapM_ (uncurry enact') as
  where
    invert (res, st') = either Left (const $ Right st') res
    enact' u a = withExceptT (AtomicFailure a) $ enact u a
    enact u (ActCreateJob spec) = createJob u cl spec
    enact _ (ActKillJob   name) = killJob name
    enact _ (ActPatchJob n pat) = patchDepends n pat
    enact _ (ActDeleteJob name) = deleteJob name
    enact _ (ActCreateBox spec) = createBox spec
    enact _ (ActSealBox   name) = sealBox name
    enact _ (ActDeleteBox name) = deleteBox name

-- Only check on active jobs; terminated jobs shouldn't change status
-- | All jobs that should be queried on the scheduler.