As a workaround, I'm spinning trying to successfully connect first before trying to connect for real:
-- | Try the TCP connection and see if you can connect...
--
tryTCPClient :: Int -> ClientSettings -> IO ()
tryTCPClient microseconds settings = do
ok <- newIORef False
void $ timeout microseconds $ runTCPClient settings $ const $
writeIORef ok True
ok' <- readIORef ok
unless ok' $
tryTCPClient microseconds settings
-- | Wrap runTCPClient with a connect timeout.
--
-- Tries the TCP connection first, and the runs the regular runTCPClient.
-- Of course, this only enforces a TCP connect timeout on the first connect.
-- The second TCP connect has no timeout :(
--
runTCPClient' :: Int -> ClientSettings -> (AppData -> IO a) -> IO a
runTCPClient' microseconds settings action = do
tryTCPClient microseconds settings
runTCPClient settings action