module Monitor (
MState(..),
RebootT,
Monitor,
runMonitor,
restart,
unloadplugs,
setrebootvar,
threadQuit,
cGetLine,
cGetLines,
cprint,
mlog,
serverNum,
exit
) where
import Control.Concurrent.STM
import Control.Monad.State
import System.Plugins
import Control.Concurrent
import System.Exit
import System.IO
import Data.Map
import qualified Config as C
import Logger
import API
import Net
data MState = MState {
rebootvar :: TMVar Int,
rchan :: Chan ReportChan,
servers :: Map String (Handle,C.Server),
conf :: C.Config,
lFile :: FilePath,
reboot :: RebootT,
imodule :: Module,
pmodules :: [Module]
}
type RebootT = (Module -> MState -> IO ())
type Monitor a = StateT MState IO a
-- monitor api
runMonitor :: Monitor a -> MState -> IO a
runMonitor = evalStateT
restart :: Monitor ()
restart = do
m <- gets imodule
r <- gets reboot
st <- get
io $ r m st
unloadplugs = do
p <- gets pmodules
io $ mapM_ unload p
threadQuit s = do
st <- get
p <- gets servers
let new = delete s p
put $ st{servers=new}
exit = do
io $ putStrLn "all servers closed, infinity exiting..."
io $ (exitWith ExitSuccess)
setrebootvar :: Monitor ()
setrebootvar = do
s <- gets rebootvar
io (atomically $ putTMVar s 1)
cGetLines :: Monitor [ReportChan]
cGetLines = do
r <- gets rchan
c <- io $ getChanContents r
return c
cGetLine :: Monitor ReportChan
cGetLine = cGetLines >>= return . head
cprint = io . putStrLn
mlog :: PrintStatus -> String -> Monitor ()
mlog p s = do
f <- gets lFile
io $ logger f p (concat ["Monitor: ",s])
serverNum :: Monitor Int
serverNum = gets servers >>= return . size
-- convenience
io :: IO a -> Monitor a
io = liftIO