]> gitweb.michael.orlitzky.com - dead/htsn.git/commitdiff
Use the round-robin approach to choosing a hostname.
authorMichael Orlitzky <michael@orlitzky.com>
Sat, 23 Nov 2013 22:29:16 +0000 (17:29 -0500)
committerMichael Orlitzky <michael@orlitzky.com>
Sat, 23 Nov 2013 22:29:16 +0000 (17:29 -0500)
Time out the login after 5s if it has not completed.
Add some comments.

src/CommandLine.hs
src/Main.hs

index 40a1ac887fe3a78de7fa762f8290e3a655ee4248..d710b18c0c5d040468ef98aa0781e3f34547670e 100644 (file)
@@ -46,6 +46,8 @@ arg_spec =
     password         = def &= typ "PASSWORD" &= help password_help,
     output_directory = def &= typDir         &= help output_directory_help,
     username         = def &= typ "USERNAME" &= help username_help,
+    -- Using "def" below for the FeedHosts causes the list to show up in
+    -- reverse. Don't ask me why.
     feed_hosts       = def &= typ "HOSTNAMES" }
   &= program program_name
   &= summary my_summary
index 34d775b672ad92b683be5c70e151a309137d50d3..415517f323612e40bd5ef45490f73cb674e9abab 100644 (file)
@@ -6,7 +6,7 @@ where
 
 import Control.Concurrent (threadDelay)
 import Control.Exception.Base (bracket)
-import Control.Monad (forever, when)
+import Control.Monad (when)
 import Data.List (isPrefixOf)
 import Data.Maybe (isNothing)
 import Data.Monoid ((<>))
@@ -28,6 +28,7 @@ import System.IO (
   stderr,
   stdout )
 import System.IO.Error (catchIOError)
+import System.Timeout (timeout)
 
 import CommandLine (get_args)
 import Configuration (Configuration(..), merge_optional)
@@ -123,19 +124,34 @@ log_in cfg h = do
     recv_prompt :: Handle -> IO String
     recv_prompt = recv_chars 10
 
-connect_and_loop :: Configuration -> IO ()
-connect_and_loop cfg =
+connect_and_loop :: Configuration -> String -> IO ()
+connect_and_loop cfg host = do
+  putStrLn $ "Connecting to " ++ host ++ "..."
   bracket acquire_handle release_handle action
+  return ()
   where
-    --acquire_handle = connectTo "feed1.sportsnetwork.com" (PortNumber 4500)
-    acquire_handle = connectTo "feed2.sportsnetwork.com" (PortNumber 4500)
-    --acquire_handle = connectTo "127.0.0.1" (PortNumber 13337)
+    five_seconds :: Int
+    five_seconds = 5000000
+
+    acquire_handle = connectTo host (PortNumber 4500)
     release_handle = hClose
     action h = do
       -- No buffering anywhere.
       hSetBuffering h NoBuffering
-      log_in cfg h
-      loop cfg h []
+
+      -- The feed is often unresponsive after we send out username. It
+      -- happens in a telnet session, too (albeit less frequently?),
+      -- so there might be a bug on their end.
+      --
+      -- If we dump the packets with tcpdump, it looks like their
+      -- software is getting confused: they send us some XML in
+      -- the middle of the log-in procedure. In any case, the easiest
+      -- fix is to disconnect and try again.
+      --
+      login_worked <- timeout five_seconds $ log_in cfg h
+      case login_worked of
+        Nothing -> putStrLn "Login timed out (5s)."
+        Just _ ->  loop cfg h []
 
 
 -- | A wrapper around threadDelay which takes seconds instead of
@@ -155,6 +171,10 @@ main = do
   -- prefering the command-line ones.
   let opt_config = rc_cfg <> cmd_cfg
 
+  -- This is necessary because if the user specifies an empty list of
+  -- hostnames in e.g. the config file, we want to bail rather than
+  -- fall back on the default list (which gets merged from a
+  -- Configuration below).
   when (null $ get_feed_hosts (OC.feed_hosts opt_config)) $ do
     report_error "ERROR: no feed hosts supplied."
     exitWith (ExitFailure exit_no_feed_hosts)
@@ -174,6 +194,13 @@ main = do
   hSetBuffering stderr NoBuffering
   hSetBuffering stdout NoBuffering
 
-  forever $ do
-    catchIOError (connect_and_loop cfg) (report_error . show)
-    thread_sleep 10 -- Wait 10s before attempting to reconnect.
+  round_robin cfg 0
+
+  where
+    round_robin :: Configuration -> Int -> IO ()
+    round_robin cfg feed_host_idx = do
+      let hosts = get_feed_hosts $ feed_hosts cfg
+      let host = hosts !! feed_host_idx
+      catchIOError (connect_and_loop cfg host) (report_error . show)
+      thread_sleep 10 -- Wait 10s before attempting to reconnect.
+      round_robin cfg $ (feed_host_idx + 1) `mod` (length hosts)