{-| Module : Gargantext.API.Worker Description : New-style Worker API (no more servant-job) Copyright : (c) CNRS, 2024-Present License : AGPL + CECILL v3 Maintainer : team@gargantext.org Stability : experimental Portability : POSIX -} {-# LANGUAGE TypeOperators #-} module Gargantext.API.Worker where import Data.Aeson qualified as JSON import Data.ByteString.Lazy qualified as BL import Data.Text.Encoding qualified as TE import Gargantext.API.Prelude (IsGargServer) import Gargantext.Core.Worker.Jobs (sendJob) import Gargantext.Core.Worker.Jobs.Types (Job(..), getWorkerMNodeId) import Gargantext.Core.Worker.Types (JobInfo(..)) import Gargantext.Prelude import Gargantext.System.Logging (logM, LogLevel(..)) import Servant.API ((:>), (:-), JSON, Post, ReqBody) import Servant.Server.Generic (AsServerT) data WorkerAPI contentType input mode = WorkerAPI { workerAPIPost :: mode :- ReqBody contentType input :> Post '[JSON] JobInfo } deriving Generic serveWorkerAPI :: IsGargServer env err m => (input -> Job) -> WorkerAPI contentType input (AsServerT m) serveWorkerAPI f = serveWorkerAPIM (pure . f) serveWorkerAPIM :: IsGargServer env err m => (input -> m Job) -> WorkerAPI contentType input (AsServerT m) serveWorkerAPIM mkJob = WorkerAPI { workerAPIPost } where workerAPIPost i = do job <- mkJob i logM DEBUG $ "[serveWorkerAPI] sending job " <> TE.decodeUtf8 (BL.toStrict $ JSON.encode job) mId <- sendJob job pure $ JobInfo { _ji_message_id = mId , _ji_mNode_id = getWorkerMNodeId job } serveWorkerAPIEJob :: (MonadError err m, IsGargServer env err m) => (input -> Either err Job) -> WorkerAPI contentType input (AsServerT m) serveWorkerAPIEJob f = WorkerAPI { workerAPIPost } where workerAPIPost i = do let eJob = f i case eJob of Left err -> throwError err Right job -> do mId <- sendJob job pure $ JobInfo { _ji_message_id = mId , _ji_mNode_id = getWorkerMNodeId job }