module Control.Concurrent.Capataz.Internal.Worker where
import Protolude
import Control.Concurrent.Async (asyncWithUnmask)
import Data.Time.Clock (getCurrentTime)
import qualified Data.UUID.V4 as UUID
import qualified Control.Concurrent.Capataz.Internal.Process as Process
import qualified Control.Concurrent.Capataz.Internal.Util as Util
import Control.Concurrent.Capataz.Internal.Types
workerMain
:: ParentSupervisorEnv
-> WorkerOptions
-> WorkerId
-> RestartCount
-> IO Worker
workerMain env@ParentSupervisorEnv { supervisorNotify } workerOptions@WorkerOptions { workerName, workerAction } workerId restartCount
= do
workerCreationTime <- getCurrentTime
workerAsync <- asyncWithUnmask $ \unmask -> do
eResult <- try $ do
Util.setProcessThreadName workerId workerName
unmask workerAction
resultEvent <- case eResult of
Left err -> Process.handleProcessException unmask
env
(WorkerSpec workerOptions)
workerId
restartCount
err
Right _ -> Process.handleProcessCompletion unmask
env
(WorkerSpec workerOptions)
workerId
restartCount
supervisorNotify (MonitorEvent resultEvent)
return Worker
{ workerId
, workerName
, workerAsync
, workerCreationTime
, workerOptions
}
forkWorker
:: ParentSupervisorEnv
-> WorkerOptions
-> Maybe (WorkerId, RestartCount)
-> IO Worker
forkWorker env workerOptions mRestartInfo = do
(workerId, restartCount) <- case mRestartInfo of
Just (workerId, restartCount) -> pure (workerId, restartCount)
Nothing -> (,) <$> UUID.nextRandom <*> pure 0
worker <- workerMain env workerOptions workerId restartCount
Process.notifyProcessStarted mRestartInfo env (WorkerProcess worker)
return worker