graphql-engine/server/src-exec/Main.hs

106 lines
4.0 KiB
Haskell

{-# LANGUAGE RecordWildCards #-}
module Main where
import Control.Exception
import Data.Int (Int64)
import Data.Text.Conversions (convertText)
import Data.Time.Clock.POSIX (getPOSIXTime)
import Hasura.App
import Hasura.Logging (Hasura)
import Hasura.Prelude
import Hasura.RQL.DDL.Metadata (fetchMetadataFromHdbTables)
import Hasura.RQL.DDL.Schema
import Hasura.RQL.Types
import Hasura.Server.Init
import Hasura.Server.Migrate (downgradeCatalog, dropCatalog)
import Hasura.Server.Version
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Char8 as BLC
import qualified Data.Environment as Env
import qualified Database.PG.Query as Q
import qualified Hasura.Tracing as Tracing
import qualified System.Exit as Sys
import qualified System.Metrics as EKG
import qualified System.Posix.Signals as Signals
main :: IO ()
main = do
tryExit $ do
args <- parseArgs
env <- Env.getEnvironment
unAppM (runApp env args)
where
tryExit io = try io >>= \case
Left (ExitException _code msg) -> BC.putStrLn msg >> Sys.exitFailure
Right r -> return r
runApp :: Env.Environment -> HGEOptions Hasura -> AppM ()
runApp env (HGEOptionsG rci hgeCmd) =
withVersion $$(getVersionFromEnvironment) $ case hgeCmd of
HCServe serveOptions -> do
(initCtx, initTime) <- initialiseCtx env hgeCmd rci
ekgStore <- liftIO do
s <- EKG.newStore
EKG.registerGcMetrics s
let getTimeMs :: IO Int64
getTimeMs = (round . (* 1000)) `fmap` getPOSIXTime
EKG.registerCounter "ekg.server_timestamp_ms" getTimeMs s
pure s
let shutdownApp = return ()
-- Catches the SIGTERM signal and initiates a graceful shutdown.
-- Graceful shutdown for regular HTTP requests is already implemented in
-- Warp, and is triggered by invoking the 'closeSocket' callback.
-- We only catch the SIGTERM signal once, that is, if the user hits CTRL-C
-- once again, we terminate the process immediately.
_ <- liftIO $ Signals.installHandler
Signals.sigTERM
(Signals.CatchOnce (shutdownGracefully initCtx))
Nothing
runHGEServer env serveOptions initCtx Nothing initTime shutdownApp Nothing ekgStore
HCExport -> do
(initCtx, _) <- initialiseCtx env hgeCmd rci
res <- runTx' initCtx fetchMetadataFromHdbTables Q.ReadCommitted
either (printErrJExit MetadataExportError) printJSON res
HCClean -> do
(initCtx, _) <- initialiseCtx env hgeCmd rci
res <- runTx' initCtx dropCatalog Q.ReadCommitted
either (printErrJExit MetadataCleanError) (const cleanSuccess) res
HCExecute -> do
(InitCtx{..}, _) <- initialiseCtx env hgeCmd rci
queryBs <- liftIO BL.getContents
let sqlGenCtx = SQLGenCtx False
res <- runAsAdmin _icPgPool sqlGenCtx _icHttpManager $ do
schemaCache <- buildRebuildableSchemaCache env
execQuery env queryBs
& Tracing.runTraceTWithReporter Tracing.noReporter "execute"
& runHasSystemDefinedT (SystemDefined False)
& runCacheRWT schemaCache
& fmap (\(res, _, _) -> res)
either (printErrJExit ExecuteProcessError) (liftIO . BLC.putStrLn) res
HCDowngrade opts -> do
(InitCtx{..}, initTime) <- initialiseCtx env hgeCmd rci
let sqlGenCtx = SQLGenCtx False
res <- downgradeCatalog opts initTime
& runAsAdmin _icPgPool sqlGenCtx _icHttpManager
either (printErrJExit DowngradeProcessError) (liftIO . print) res
HCVersion -> liftIO $ putStrLn $ "Hasura GraphQL Engine: " ++ convertText currentVersion
where
runTx' initCtx tx txIso =
liftIO $ runExceptT $ Q.runTx (_icPgPool initCtx) (txIso, Nothing) tx
cleanSuccess = liftIO $ putStrLn "successfully cleaned graphql-engine related data"