{-# LANGUAGE DeriveAnyClass #-} module Yam.Server.Health where import Data.Aeson import qualified Data.HashMap.Strict as M import Data.Swagger import GHC.Generics import Servant import Yam.App import Yam.Prelude type HealthEndpoint = "health" :> Get '[JSON] HealthResult data HealthStatus = UP | DOWN deriving (Eq, Show, Generic, ToJSON) instance ToSchema HealthStatus instance ToSchema HealthResult data HealthResult = HealthResult { status :: HealthStatus , errMsg :: Maybe String , details :: M.HashMap Text HealthResult } deriving (Eq, Show, Generic, ToJSON) emptyHealth :: IO HealthResult emptyHealth = return (HealthResult UP Nothing M.empty) mergeHealth :: IO HealthStatus -> Text -> IO HealthResult -> IO HealthResult mergeHealth ios na ior = do (err,s) <- ((Nothing,) <$> ios) `catch` (\(e :: SomeException) -> return (Just (show e), DOWN)) HealthResult{..} <- ior return (HealthResult (if s == DOWN then s else status) Nothing $ M.insert na (HealthResult s err M.empty) details) healthEndpoint :: MonadIO m => IO HealthResult -> Bool -> AppT cxt m HealthResult healthEndpoint a True = liftIO a healthEndpoint a _ = liftIO a