-- TODO: Determine satisfiability before scheduling job
-- | Try to schedule a new job. UUID must be unique; best to randomly generate
-- it.
createJob :: forall m. (TS m, MonadError JobError m) => UUID -> Maybe Cluster -> Job.Spec -> m ()
createJob uuid cluster spec = do
    flip unless (throwError $ ContainerMustExist con) . has _Just =<< ES.containerUUID con
    ensureNameUnused name
    activeDeps <- namesToWaitFor deps
    satis <- stagelessSatisfy cluster spec
    let jstage = shouldBeWaiting activeDeps
    ES.insertJob $ Job.mkStatus spec jstage satis uuid mempty
    mapM_ (ES.addRevDep name) deps
    queueJob <- mkQueueJob spec uuid
    when (jstage == Queued LocalQueue) . ES.schedule $ queueJob
  where
    deps = spec ^. Job.dependsOn . Job.dependenciesList
    name = spec ^. Job.name
    con = spec ^. Job.container
createJob :: forall m. (TS m, MonadError JobError m) => UUID -> Maybe Cluster -> Job.Spec -> m ()
createJob uuid cluster spec = do
    flip unless (throwError $ ContainerMustExist con) . has _Just =<< ES.containerUUID con
    ensureNameUnused name
    activeDeps <- namesToWaitFor deps
    satis <- stagelessSatisfy cluster spec
    let jstage = shouldBeWaiting activeDeps
    ES.insertJob $ Job.mkStatus spec jstage satis uuid mempty
    mapM_ (ES.addRevDep name) deps
    queueJob <- mkQueueJob spec uuid
    when (jstage == Queued LocalQueue) . ES.schedule $ queueJob
  where
    deps = spec ^. Job.dependsOn . Job.dependenciesList
    name = spec ^. Job.name
    con = spec ^. Job.container
createJob uuid cluster spec = do
    flip unless (throwError $ ContainerMustExist con) . has _Just =<< ES.containerUUID con
    ensureNameUnused name
    activeDeps <- namesToWaitFor deps
    satis <- stagelessSatisfy cluster spec
    let jstage = shouldBeWaiting activeDeps
    ES.insertJob $ Job.mkStatus spec jstage satis uuid mempty
    mapM_ (ES.addRevDep name) deps
    queueJob <- mkQueueJob spec uuid
    when (jstage == Queued LocalQueue) . ES.schedule $ queueJob
  where
    deps = spec ^. Job.dependsOn . Job.dependenciesList
    name = spec ^. Job.name
    con = spec ^. Job.container