shrub/pkg/hs/urbit-king/lib/Urbit/King/App.hs

166 lines
4.3 KiB
Haskell
Raw Normal View History

2020-01-23 07:16:09 +03:00
{-|
Code for setting up the RIO environment.
-}
module Urbit.King.App
2020-05-13 22:35:57 +03:00
( KingEnv
, runKingEnvStderr
, runKingEnvLogFile
, runKingEnvNoLog
, PierEnv
, runPierEnv
, 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
import Urbit.King.Config
import Urbit.Prelude
2020-05-13 22:35:57 +03:00
import System.Directory (createDirectoryIfMissing, getHomeDirectory)
import System.Posix.Internals (c_getpid)
import System.Posix.Types (CPid(..))
import System.Random (randomIO)
2020-05-22 21:12:28 +03:00
-- KingEnv ---------------------------------------------------------------------
2020-02-04 04:27:16 +03:00
class HasStderrLogFunc a where
2020-05-13 22:35:57 +03:00
stderrLogFuncL :: Lens' a LogFunc
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
}
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
2020-05-13 22:35:57 +03:00
instance HasProcId KingEnv where
procIdL = kingEnvProcId
2020-05-13 22:35:57 +03:00
instance HasKingId KingEnv where
kingIdL = kingEnvKingId
2020-02-04 04:27:16 +03:00
2020-05-13 22:35:57 +03:00
-- Running KingEnvs ------------------------------------------------------------
2020-05-13 22:35:57 +03:00
runKingEnvStderr :: RIO KingEnv a -> IO a
runKingEnvStderr inner = do
logOptions <-
logOptionsHandle stderr True <&> setLogUseTime True <&> setLogUseLoc False
2020-05-13 22:35:57 +03:00
withLogFunc logOptions $ \logFunc -> runKingEnv logFunc logFunc inner
2020-02-04 04:27:16 +03:00
2020-05-13 22:35:57 +03:00
runKingEnvLogFile :: RIO KingEnv a -> IO a
runKingEnvLogFile inner = withLogFileHandle $ \h -> do
logOptions <-
logOptionsHandle h True <&> setLogUseTime True <&> setLogUseLoc False
stderrLogOptions <-
logOptionsHandle stderr True <&> setLogUseTime False <&> setLogUseLoc False
withLogFunc stderrLogOptions $ \stderrLogFunc -> withLogFunc logOptions
$ \logFunc -> runKingEnv logFunc stderrLogFunc inner
withLogFileHandle :: (Handle -> IO a) -> IO a
withLogFileHandle act = do
2020-05-13 22:35:57 +03:00
home <- getHomeDirectory
let logDir = home </> ".urbit"
createDirectoryIfMissing True logDir
withFile (logDir </> "king.log") AppendMode $ \handle -> do
hSetBuffering handle LineBuffering
act handle
runKingEnvNoLog :: RIO KingEnv a -> IO a
runKingEnvNoLog act = withFile "/dev/null" AppendMode $ \handle -> do
logOptions <- logOptionsHandle handle True
withLogFunc logOptions $ \logFunc -> runKingEnv logFunc logFunc act
runKingEnv :: LogFunc -> LogFunc -> RIO KingEnv a -> IO a
runKingEnv logFunc stderr action = do
kid <- randomIO
CPid pid <- c_getpid
runRIO (KingEnv logFunc stderr kid pid) action
-- 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
}
makeLenses ''PierEnv
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
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
2020-05-13 22:35:57 +03:00
instance HasPierConfig PierEnv where
pierConfigL = pierEnvPierConfig
2020-05-13 22:35:57 +03:00
instance HasNetworkConfig PierEnv where
networkConfigL = pierEnvNetworkConfig
2020-05-13 22:35:57 +03:00
instance HasProcId PierEnv where
2020-05-22 21:12:28 +03:00
procIdL = kingEnvL . kingEnvProcId
2020-05-13 22:35:57 +03:00
-- Running Pier Envs -----------------------------------------------------------
2020-05-13 22:35:57 +03:00
runPierEnv :: PierConfig -> NetworkConfig -> RIO PierEnv a -> RIO KingEnv a
runPierEnv pierConfig networkConfig action = do
app <- ask
2020-05-13 22:35:57 +03:00
let pierEnv = PierEnv { _pierEnvKingEnv = app
, _pierEnvPierConfig = pierConfig
, _pierEnvNetworkConfig = networkConfig
}
2020-05-13 22:35:57 +03:00
io (runRIO pierEnv action)