----------------------------------------------------------------------------- -- -- Module : Control.Concurrent.Network.Process -- Copyright : (C) 2010, Paul Sonkoly -- License : BSD style -- -- Maintainer : Paul Sonkoly -- Stability : provisional -- Portability : -- -- | General idea is having one dedicated master process and an arbitrary -- number of slave processes. -- ----------------------------------------------------------------------------- module Control.Concurrent.Network.Process ( -- * Functions initProcess ) where import System.IO import Network import Control.Concurrent.Network.Master import Control.Concurrent.Network.Slave import System.Console.GetOpt import System.Environment import System.Exit import System.Log.Logger data Options = Options { optMaster :: Bool , optChildNum :: Int , optDbgLevel :: Priority , optMIP :: HostName , optMPort :: PortID } defaultOptions = Options { optMaster = False , optChildNum = 1 , optDbgLevel = WARNING , optMIP = "127.0.0.1" , optMPort = PortNumber 9999 } options :: [ OptDescr (Options -> IO Options) ] options = [ Option "m" ["child-number"] (ReqArg (\ n opt -> return opt {optMaster = True, optChildNum = read n}) "[INT]") "Master process only: number of child processes." , Option "d" ["debug-level"] (ReqArg (\ lev opt -> return opt { optDbgLevel = read lev }) "[DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY]") "Debug level" , Option "i" ["master-ip"] (ReqArg (\ ip opt -> return opt { optMIP = read ip }) "[HOSTNAME]") "Slave process only, ip address or hostname of the master process." , Option "p" ["master-port"] (ReqArg (\ port opt -> return opt { optMPort = PortNumber $ fromIntegral $ read port }) "[PORT]") $ "Port for the master process to listen on, or for slave processes " ++ "to connect to" , Option "h" ["help"] (NoArg (\_ -> do prg <- getProgName hPutStrLn stderr (usageInfo prg options) exitWith ExitSuccess)) "Show help" ] -- | Convinience function. It calls either 'initMaster' or -- 'initSlave' depending on whether we have -m on the command line -- or not. If -m is specified the following argument should be the -- number of slaves to wait for. -- -- Returns in the slave processes with the NC context. -- Does not return in the master process. initProcess :: IO NCContext initProcess = do args <- getArgs (acts, _, msgs) <- return $ getOpt RequireOrder options args putStrLn $ concat msgs opts <- foldl (>>=) (return defaultOptions) acts logger <- getRootLogger saveGlobalLogger $ setLevel (optDbgLevel opts) logger if optMaster opts then do initMaster (optChildNum opts) $ optMPort opts exitSuccess else initSlave (optMIP opts) $ optMPort opts