Hi Mark,

From reading the source code for runTCPClient [1], it looks like a thin wrapper around getSocketFamilyTCP and close.

It should be sufficient to copy that definition into your project and wrap the getSocketFamilyTCP call in a timeout. You might need to import Data.Streaming.Network.Internal to get access to the AppData constructor.

Hope this helps!

[1] https://hackage.haskell.org/package/streaming-commons-0.1.18/docs/src/Data-Streaming-Network.html#runTCPClient

On Sun, Oct 15, 2017 at 9:08 AM, Mark Fine <mark.fine@gmail.com> wrote:
Hi Chris,

In my application, I'm using Data.Conduit.Network from conduit-extra directly (Data.Streaming.Network from streaming-commons indirectly). The timeout I'm interested in managing is the connection establishment timeout - how long does the connect call wait to establish a connection. I haven't been able to figure out how to control this outside of applying a non-conditional timeout to the connect call (which is a timeout on the lifetime of a connection, not a timeout on the establishment of a connection). Thanks!

Mark

On Sat, Oct 14, 2017 at 3:09 AM, Chris Wong <lambda.fairy@gmail.com> wrote:
Hi Mark,

What networking library are you using?

There should be a lower level interface which allows for managing the lifetime of a connection by hand.

Chris

On Oct 14, 2017 15:17, "Mark Fine" <mark.fine@gmail.com> wrote:
I'd like a configurable network connect timeout. Has anyone solved this reasonably?

System.Timeout.timeout times out connections, but works on the granularity of the life of the connection. Is there a reasonable way to configure a timeout around just establishing the connection? Maybe something like a conditional timeout that enables an action to disable the timeout once it expires?

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

I've also tried running the tryTCPClient in its own thread concurrently with runTCPClient and throwing an exception if it can't connect in microseconds. None of these offer an actual true connection establishment timeout.

Has anyone found a way to solve this? Thanks!

Mark



_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.




--
Chris Wong (https://lambda.xyz)

"I had not the vaguest idea what this meant and when I could not remember the words, my tutor threw the book at my head, which did not stimulate my intellect in any way." -- Bertrand Russell