where
import Control.Concurrent ( threadDelay )
-import Control.Exception.Base ( bracket )
+import Control.Exception ( bracket, throw )
import Control.Monad ( when )
import Data.List ( isPrefixOf )
import Data.Maybe ( isNothing )
exit_no_username,
exit_pidfile_exists )
import FeedHosts ( FeedHosts(..) )
-import Logging ( init_logging )
+import Network.Services.TSN.Logging ( init_logging )
import qualified OptionalConfiguration as OC (
OptionalConfiguration(..),
from_rc )
-import Report (
+import Network.Services.TSN.Report (
report_debug,
report_info,
report_warning,
report_error )
-import Terminal ( display_sent )
+import Network.Services.TSN.Terminal ( display_sent )
import Xml ( parse_xmlfid )
import Unix ( full_daemonize )
-- logging before the missing parameter checks below so that we can
-- log the errors.
let cfg = (def :: Configuration) `merge_optional` opt_config
- init_logging (log_file cfg) (log_level cfg) (syslog cfg)
+ init_logging (log_level cfg) (log_file cfg) (syslog cfg)
-- Check the optional config for missing required options. This is
-- necessary because if the user specifies an empty list of
-- If we were asked to daemonize, do that; otherwise just run the thing.
if (daemonize cfg)
- then full_daemonize cfg run_program
+ then try_daemonize cfg run_program
else run_program
where
catchIOError (connect_and_parse cfg host) (report_error . show)
thread_sleep 5 -- Wait 5s before attempting to reconnect.
round_robin cfg $ (feed_host_idx + 1) `mod` (length hosts)
+
+
+ -- | A exception handler around full_daemonize. If full_daemonize
+ -- doesn't work, we report the error and crash. This is fine; we
+ -- only need the program to be resilient once it actually starts.
+ --
+ try_daemonize :: Configuration -> IO () -> IO ()
+ try_daemonize cfg program =
+ catchIOError
+ (full_daemonize cfg program)
+ (\e -> do
+ report_error (show e)
+ throw e)