2020-01-23 07:16:09 +03:00
|
|
|
{-|
|
|
|
|
Code for setting up the RIO environment.
|
|
|
|
-}
|
2020-01-24 08:28:38 +03:00
|
|
|
module Urbit.King.App
|
2020-05-13 22:35:57 +03:00
|
|
|
( KingEnv
|
|
|
|
, runKingEnvStderr
|
|
|
|
, runKingEnvLogFile
|
|
|
|
, runKingEnvNoLog
|
2020-06-07 02:03:20 +03:00
|
|
|
, kingEnvKillSignal
|
|
|
|
, killKingActionL
|
|
|
|
, onKillKingSigL
|
2020-05-13 22:35:57 +03:00
|
|
|
, PierEnv
|
|
|
|
, runPierEnv
|
2020-06-07 02:03:20 +03:00
|
|
|
, killPierActionL
|
|
|
|
, onKillPierSigL
|
2020-05-13 22:35:57 +03:00
|
|
|
, HasStderrLogFunc(..)
|
|
|
|
, HasKingId(..)
|
|
|
|
, HasProcId(..)
|
2020-05-22 21:12:28 +03:00
|
|
|
, HasKingEnv(..)
|
|
|
|
, HasPierEnv(..)
|
|
|
|
, module Urbit.King.Config
|
2020-05-13 22:35:57 +03:00
|
|
|
)
|
|
|
|
where
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-01-24 08:28:38 +03:00
|
|
|
import Urbit.King.Config
|
|
|
|
import Urbit.Prelude
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-08-15 05:25:07 +03:00
|
|
|
import System.Directory ( createDirectoryIfMissing
|
|
|
|
, getAppUserDataDirectory
|
|
|
|
)
|
2020-05-13 22:35:57 +03:00
|
|
|
import System.Posix.Internals (c_getpid)
|
|
|
|
import System.Posix.Types (CPid(..))
|
|
|
|
import System.Random (randomIO)
|
2020-06-11 02:41:09 +03:00
|
|
|
import Urbit.King.App.Class (HasStderrLogFunc(..))
|
2019-12-19 14:32:56 +03:00
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
|
2020-08-15 05:25:07 +03:00
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
-- KingEnv ---------------------------------------------------------------------
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
class HasKingId a where
|
|
|
|
kingIdL :: Lens' a Word16
|
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
class HasProcId a where
|
|
|
|
procIdL :: Lens' a Int32
|
2020-05-13 22:35:57 +03:00
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
class (HasLogFunc a, HasStderrLogFunc a, HasKingId a, HasProcId a)
|
|
|
|
=> HasKingEnv a
|
|
|
|
where
|
|
|
|
kingEnvL :: Lens' a KingEnv
|
2020-05-13 22:35:57 +03:00
|
|
|
|
|
|
|
data KingEnv = KingEnv
|
|
|
|
{ _kingEnvLogFunc :: !LogFunc
|
|
|
|
, _kingEnvStderrLogFunc :: !LogFunc
|
|
|
|
, _kingEnvKingId :: !Word16
|
|
|
|
, _kingEnvProcId :: !Int32
|
2020-06-07 02:03:20 +03:00
|
|
|
, _kingEnvKillSignal :: !(TMVar ())
|
2020-05-13 22:35:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
makeLenses ''KingEnv
|
2020-02-04 04:27:16 +03:00
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
instance HasKingEnv KingEnv where
|
|
|
|
kingEnvL = id
|
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasLogFunc KingEnv where
|
|
|
|
logFuncL = kingEnvLogFunc
|
2020-02-04 04:27:16 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasStderrLogFunc KingEnv where
|
|
|
|
stderrLogFuncL = kingEnvStderrLogFunc
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasProcId KingEnv where
|
|
|
|
procIdL = kingEnvProcId
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasKingId KingEnv where
|
|
|
|
kingIdL = kingEnvKingId
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-02-04 04:27:16 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
-- Running KingEnvs ------------------------------------------------------------
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-06-11 05:02:09 +03:00
|
|
|
runKingEnvStderr :: Bool -> RIO KingEnv a -> IO a
|
|
|
|
runKingEnvStderr verb inner = do
|
2020-05-13 22:35:57 +03:00
|
|
|
logOptions <-
|
2020-06-11 05:02:09 +03:00
|
|
|
logOptionsHandle stderr verb <&> setLogUseTime True <&> setLogUseLoc False
|
2019-12-19 14:32:56 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
withLogFunc logOptions $ \logFunc -> runKingEnv logFunc logFunc inner
|
2020-02-04 04:27:16 +03:00
|
|
|
|
2020-08-15 05:25:07 +03:00
|
|
|
runKingEnvLogFile :: Bool -> Maybe FilePath -> RIO KingEnv a -> IO a
|
|
|
|
runKingEnvLogFile verb fileM inner = do
|
|
|
|
logFile <- case fileM of
|
|
|
|
Just f -> pure f
|
|
|
|
Nothing -> defaultLogFile
|
|
|
|
withLogFileHandle logFile $ \h -> do
|
|
|
|
logOptions <-
|
|
|
|
logOptionsHandle h verb <&> setLogUseTime True <&> setLogUseLoc False
|
|
|
|
stderrLogOptions <-
|
|
|
|
logOptionsHandle stderr verb <&> setLogUseTime False <&> setLogUseLoc False
|
|
|
|
|
|
|
|
withLogFunc stderrLogOptions $ \stderrLogFunc -> withLogFunc logOptions
|
|
|
|
$ \logFunc -> runKingEnv logFunc stderrLogFunc inner
|
|
|
|
|
|
|
|
withLogFileHandle :: FilePath -> (Handle -> IO a) -> IO a
|
|
|
|
withLogFileHandle f act =
|
|
|
|
withFile f AppendMode $ \handle -> do
|
2020-05-13 22:35:57 +03:00
|
|
|
hSetBuffering handle LineBuffering
|
|
|
|
act handle
|
|
|
|
|
2020-08-15 05:25:07 +03:00
|
|
|
defaultLogFile :: IO FilePath
|
|
|
|
defaultLogFile = do
|
|
|
|
logDir <- getAppUserDataDirectory "urbit"
|
|
|
|
createDirectoryIfMissing True logDir
|
|
|
|
pure (logDir </> "king.log")
|
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
runKingEnvNoLog :: RIO KingEnv a -> IO a
|
2020-08-15 05:25:07 +03:00
|
|
|
runKingEnvNoLog act = runKingEnv mempty mempty act
|
2020-05-13 22:35:57 +03:00
|
|
|
|
|
|
|
runKingEnv :: LogFunc -> LogFunc -> RIO KingEnv a -> IO a
|
|
|
|
runKingEnv logFunc stderr action = do
|
|
|
|
kid <- randomIO
|
|
|
|
CPid pid <- c_getpid
|
2020-06-07 02:03:20 +03:00
|
|
|
kil <- newEmptyTMVarIO
|
|
|
|
runRIO (KingEnv logFunc stderr kid pid kil) action
|
|
|
|
|
|
|
|
|
|
|
|
-- KingEnv Utils ---------------------------------------------------------------
|
|
|
|
|
|
|
|
onKillKingSigL :: HasKingEnv e => Getter e (STM ())
|
|
|
|
onKillKingSigL = kingEnvL . kingEnvKillSignal . to readTMVar
|
|
|
|
|
|
|
|
killKingActionL :: HasKingEnv e => Getter e (STM ())
|
|
|
|
killKingActionL =
|
|
|
|
kingEnvL . kingEnvKillSignal . to (\kil -> void (tryPutTMVar kil ()))
|
2020-05-13 22:35:57 +03:00
|
|
|
|
|
|
|
|
|
|
|
-- PierEnv ---------------------------------------------------------------------
|
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
class (HasKingEnv a, HasPierConfig a, HasNetworkConfig a) => HasPierEnv a where
|
|
|
|
pierEnvL :: Lens' a PierEnv
|
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
data PierEnv = PierEnv
|
|
|
|
{ _pierEnvKingEnv :: !KingEnv
|
|
|
|
, _pierEnvPierConfig :: !PierConfig
|
|
|
|
, _pierEnvNetworkConfig :: !NetworkConfig
|
2020-06-07 02:03:20 +03:00
|
|
|
, _pierEnvKillSignal :: !(TMVar ())
|
2020-05-13 22:35:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
makeLenses ''PierEnv
|
2020-01-11 03:39:31 +03:00
|
|
|
|
2020-05-22 21:12:28 +03:00
|
|
|
instance HasKingEnv PierEnv where
|
|
|
|
kingEnvL = pierEnvKingEnv
|
|
|
|
|
|
|
|
instance HasPierEnv PierEnv where
|
|
|
|
pierEnvL = id
|
|
|
|
|
|
|
|
instance HasKingId PierEnv where
|
|
|
|
kingIdL = kingEnvL . kingEnvKingId
|
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasStderrLogFunc PierEnv where
|
2020-05-22 21:12:28 +03:00
|
|
|
stderrLogFuncL = kingEnvL . stderrLogFuncL
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasLogFunc PierEnv where
|
2020-05-22 21:12:28 +03:00
|
|
|
logFuncL = kingEnvL . logFuncL
|
|
|
|
|
|
|
|
instance HasPierPath PierEnv where
|
|
|
|
pierPathL = pierEnvPierConfig . pierPathL
|
|
|
|
|
|
|
|
instance HasDryRun PierEnv where
|
|
|
|
dryRunL = pierEnvPierConfig . dryRunL
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasPierConfig PierEnv where
|
|
|
|
pierConfigL = pierEnvPierConfig
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasNetworkConfig PierEnv where
|
|
|
|
networkConfigL = pierEnvNetworkConfig
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
instance HasProcId PierEnv where
|
2020-05-22 21:12:28 +03:00
|
|
|
procIdL = kingEnvL . kingEnvProcId
|
2019-12-17 17:31:50 +03:00
|
|
|
|
|
|
|
|
2020-06-07 02:03:20 +03:00
|
|
|
-- PierEnv Utils ---------------------------------------------------------------
|
|
|
|
|
|
|
|
onKillPierSigL :: HasPierEnv e => Getter e (STM ())
|
|
|
|
onKillPierSigL = pierEnvL . pierEnvKillSignal . to readTMVar
|
|
|
|
|
|
|
|
killPierActionL :: HasPierEnv e => Getter e (STM ())
|
|
|
|
killPierActionL =
|
|
|
|
pierEnvL . pierEnvKillSignal . to (\kil -> void (tryPutTMVar kil ()))
|
|
|
|
|
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
-- Running Pier Envs -----------------------------------------------------------
|
2019-12-17 17:31:50 +03:00
|
|
|
|
2020-06-07 02:03:20 +03:00
|
|
|
runPierEnv
|
|
|
|
:: PierConfig -> NetworkConfig -> TMVar () -> RIO PierEnv a -> RIO KingEnv a
|
|
|
|
runPierEnv pierConfig networkConfig vKill action = do
|
2020-05-13 21:29:50 +03:00
|
|
|
app <- ask
|
2020-01-11 03:39:31 +03:00
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
let pierEnv = PierEnv { _pierEnvKingEnv = app
|
|
|
|
, _pierEnvPierConfig = pierConfig
|
|
|
|
, _pierEnvNetworkConfig = networkConfig
|
2020-06-07 02:03:20 +03:00
|
|
|
, _pierEnvKillSignal = vKill
|
2020-05-13 21:29:50 +03:00
|
|
|
}
|
|
|
|
|
2020-05-13 22:35:57 +03:00
|
|
|
io (runRIO pierEnv action)
|