module IHP.Job.Types.Worker
( Worker (..)
, JobWorkerArgs (..)
, JobWorker (..)
, JobWorkerProcess (..)
, JobWorkerProcessMessage (..)
) where

import IHP.Prelude
import IHP.FrameworkConfig.Types (FrameworkConfig)
import qualified IHP.PGListener as PGListener
import Control.Monad.Trans.Resource (ResourceT, ReleaseKey)
import Control.Concurrent.STM (TBQueue, TVar)

class Worker application where
    workers :: application -> [JobWorker]

data JobWorkerArgs = JobWorkerArgs
    { JobWorkerArgs -> UUID
workerId :: UUID
    , JobWorkerArgs -> ModelContext
modelContext :: ModelContext
    , JobWorkerArgs -> FrameworkConfig
frameworkConfig :: FrameworkConfig
    , JobWorkerArgs -> PGListener
pgListener :: PGListener.PGListener
    }

newtype JobWorker = JobWorker (JobWorkerArgs -> ResourceT IO JobWorkerProcess)

data JobWorkerProcess
    = JobWorkerProcess
    { JobWorkerProcess -> (ReleaseKey, Async ())
dispatcher :: (ReleaseKey, Async ())
    , JobWorkerProcess -> Subscription
subscription :: PGListener.Subscription
    , JobWorkerProcess -> ReleaseKey
pollerReleaseKey :: ReleaseKey
    , JobWorkerProcess -> TBQueue JobWorkerProcessMessage
action :: TBQueue JobWorkerProcessMessage
    , JobWorkerProcess -> Maybe ReleaseKey
staleRecoveryReleaseKey :: Maybe ReleaseKey
    , JobWorkerProcess -> TVar Int
activeCount :: TVar Int
    }

data JobWorkerProcessMessage
    = JobAvailable
    | Stop