From 3b914c1b7729f52ba96e51ad43424909acae681c Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Mon, 8 Aug 2011 20:56:20 +0200 Subject: Added exception handling, an autorestart when that happens and output in case of restart/reload --- Hsbot.hs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'Hsbot.hs') diff --git a/Hsbot.hs b/Hsbot.hs index c02b2e5..08456bf 100644 --- a/Hsbot.hs +++ b/Hsbot.hs @@ -5,13 +5,19 @@ module Hsbot import qualified Config.Dyre as Dyre import Config.Dyre.Relaunch import Control.Monad.Reader +import qualified Data.Map as M import System.Log.Logger +import qualified Network.IRC as IRC import Hsbot.Core import Hsbot.Types +import Hsbot.Utils + +data State = State (M.Map String String) deriving (Read, Show) startHsbot :: Config -> IO () startHsbot config = do + (State buffer) <- restoreTextState $ State M.empty -- checking for configuration file compilation error case configErrors config of Nothing -> return () @@ -19,16 +25,34 @@ startHsbot config = do -- initialization infoM "Hsbot" "Bot initializations" hsbotEnv <- initHsbot config + -- Handle previous exit state if it exists + die_msgs <- case M.lookup "die_msg" buffer of + Just dieMsg -> case reads dieMsg :: [(BotStatus, String)] of + (status, _):_ -> case status of + BotReload reason -> return ["hsbot reloaded, reason : " ++ reason] + BotRestart (reason, Just info) -> return ["hsbot restarted, readon : " ++ reason, "additional information: " ++ info] + BotRestart (reason, Nothing) -> return ["hsbot restarted, readon : " ++ reason] + BotExit -> return [] + _ -> return ["hsbot die_msg parsing error, this should not happen"] + Nothing -> return [] + let connhdl = envHandle hsbotEnv + tlsCtx = envTLSCtx hsbotEnv + channels = configChannels config + mapM_ (infoM "Hsbot") die_msgs + mapM_ (\msg -> mapM_ (\channel -> sendStr hsbotEnv connhdl tlsCtx . IRC.encode $ IRC.Message Nothing "PRIVMSG" [channel, msg]) channels) die_msgs -- main stuff infoM "Hsbot" "Bot core starting" status <- runReaderT runHsbot hsbotEnv infoM "Hsbot" $ "Bot core exited with status " ++ show status -- Handling exit signal case status of - BotContinue -> startHsbot config -- TODO do something not so dumb about starting over BotExit -> runReaderT terminateHsbot hsbotEnv - BotReload -> relaunchMaster Nothing -- TODO relaunchWithTextState (state { stateConfig = config }) Nothing, add a flag that prevent spawning the sockets again - BotRestart -> relaunchMaster Nothing -- TODO relaunch and kill sockets + BotReload reason -> do + runReaderT terminateHsbot hsbotEnv + relaunchWithTextState (M.singleton "die_msg" . show $ BotReload reason) Nothing -- TODO find a way to properly implement that, then insert necessary information in this MVar + BotRestart reason -> do + runReaderT terminateHsbot hsbotEnv + relaunchWithTextState (M.singleton "die_msg" . show $ BotRestart reason) Nothing hsbot :: Config -> IO () hsbot = Dyre.wrapMain $ Dyre.defaultParams -- cgit v1.2.3 From 98a1debf03cd0b5145578f823b025d2315394503 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Tue, 9 Aug 2011 23:48:15 +0200 Subject: Moved to death messages IRC output around, because those were sent too soon --- Hsbot.hs | 22 ++++++++-------------- Hsbot/Core.hs | 6 ++++-- 2 files changed, 12 insertions(+), 16 deletions(-) (limited to 'Hsbot.hs') diff --git a/Hsbot.hs b/Hsbot.hs index 08456bf..33cfa45 100644 --- a/Hsbot.hs +++ b/Hsbot.hs @@ -7,11 +7,9 @@ import Config.Dyre.Relaunch import Control.Monad.Reader import qualified Data.Map as M import System.Log.Logger -import qualified Network.IRC as IRC import Hsbot.Core import Hsbot.Types -import Hsbot.Utils data State = State (M.Map String String) deriving (Read, Show) @@ -22,27 +20,23 @@ startHsbot config = do case configErrors config of Nothing -> return () Just em -> putStrLn $ "Error: " ++ em - -- initialization - infoM "Hsbot" "Bot initializations" - hsbotEnv <- initHsbot config -- Handle previous exit state if it exists - die_msgs <- case M.lookup "die_msg" buffer of + dieMsgs <- case M.lookup "die_msg" buffer of Just dieMsg -> case reads dieMsg :: [(BotStatus, String)] of (status, _):_ -> case status of BotReload reason -> return ["hsbot reloaded, reason : " ++ reason] - BotRestart (reason, Just info) -> return ["hsbot restarted, readon : " ++ reason, "additional information: " ++ info] - BotRestart (reason, Nothing) -> return ["hsbot restarted, readon : " ++ reason] + BotRestart (reason, Just info) -> return ["hsbot restarted, reason : " ++ reason, "additional information: " ++ info] + BotRestart (reason, Nothing) -> return ["hsbot restarted, reason : " ++ reason] BotExit -> return [] _ -> return ["hsbot die_msg parsing error, this should not happen"] Nothing -> return [] - let connhdl = envHandle hsbotEnv - tlsCtx = envTLSCtx hsbotEnv - channels = configChannels config - mapM_ (infoM "Hsbot") die_msgs - mapM_ (\msg -> mapM_ (\channel -> sendStr hsbotEnv connhdl tlsCtx . IRC.encode $ IRC.Message Nothing "PRIVMSG" [channel, msg]) channels) die_msgs + mapM_ (infoM "Hsbot") dieMsgs + -- initialization + infoM "Hsbot" "Bot initializations" + hsbotEnv <- initHsbot config -- main stuff infoM "Hsbot" "Bot core starting" - status <- runReaderT runHsbot hsbotEnv + status <- runReaderT (runHsbot dieMsgs) hsbotEnv infoM "Hsbot" $ "Bot core exited with status " ++ show status -- Handling exit signal case status of diff --git a/Hsbot/Core.hs b/Hsbot/Core.hs index 49f5f5d..4dc1e92 100644 --- a/Hsbot/Core.hs +++ b/Hsbot/Core.hs @@ -53,8 +53,8 @@ initHsbot config = do , envTLS = tls , envTLSCtx = tlsCtx } -runHsbot :: Env IO BotStatus -runHsbot = do +runHsbot :: [String] -> Env IO BotStatus +runHsbot die_msgs = do botNotInitialized <- asks envBotState >>= liftIO . isEmptyMVar when botNotInitialized runFirstSteps trueRunHsbot @@ -74,6 +74,8 @@ runHsbot = do liftIO . sendStr env connhdl tlsCtx . IRC.encode $ IRC.user nickname hostname "*" (configRealname config) -- Then we join channels mapM_ (liftIO . sendStr env connhdl tlsCtx . IRC.encode . IRC.joinChan) channels + -- We advertise any death message we should + mapM_ (\msg -> mapM_ (\channel -> liftIO . sendStr env connhdl tlsCtx . IRC.encode $ IRC.Message Nothing "PRIVMSG" [channel, msg]) channels) die_msgs -- Finally we set the new bot state asks envBotState >>= liftIO . flip putMVar BotState { botPlugins = M.empty , botAccess = configAccess config -- cgit v1.2.3 From f698fd218375a0bfebd466a1cdc043427c2379b6 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Tue, 9 Aug 2011 23:55:03 +0200 Subject: Fixed mistake that prevented death message to be parsed upon restarting --- Hsbot.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Hsbot.hs') diff --git a/Hsbot.hs b/Hsbot.hs index 33cfa45..e2e771e 100644 --- a/Hsbot.hs +++ b/Hsbot.hs @@ -43,10 +43,10 @@ startHsbot config = do BotExit -> runReaderT terminateHsbot hsbotEnv BotReload reason -> do runReaderT terminateHsbot hsbotEnv - relaunchWithTextState (M.singleton "die_msg" . show $ BotReload reason) Nothing -- TODO find a way to properly implement that, then insert necessary information in this MVar + relaunchWithTextState (State $ M.singleton "die_msg" . show $ BotReload reason) Nothing -- TODO find a way to properly implement that, then insert necessary information in this MVar BotRestart reason -> do runReaderT terminateHsbot hsbotEnv - relaunchWithTextState (M.singleton "die_msg" . show $ BotRestart reason) Nothing + relaunchWithTextState (State $ M.singleton "die_msg" . show $ BotRestart reason) Nothing hsbot :: Config -> IO () hsbot = Dyre.wrapMain $ Dyre.defaultParams -- cgit v1.2.3