How does one deal with a blocking IO action in Haskell? How can I put this IO action inside a scope and manage this scope from another method? If the timeout is reached, I would just reinvoke this method. Normally in other languages, I would probably put this in a separate thread and abort it if I do not get the result in a configurable time. (The timer being external.)
In my case: I have a number of retries and let's say I want to perform an IO action with a timeout. How can I place the IO action in a timeout-ed scope so that it gets recalled after the timeout expires, if and only if the number of retries is greater 0.
Basically: given our IO action like ioMethod::IO String (I have not looked yet in the socket library for Haskell), we'll assume its a black box,
module Retry where
import IOExternal(ioMethod)
retryFunc :: Int -> IO String
retryFunc retries=do
msg<-retry 5 100 IOExternal
return msg
retry :: Int -> Int -> IOExternal -> IO String
retry retries timeout ioMethod = go retries timeout "" where
go 0 timeout ioMethod msg =
if msg=="" then return "Max Retries reached"
else return msg
go retries timeout ioMethod msg counter
= gogo retries timeout counter msg where
gogo retries timeout 0 msg = return ""
gogo retries timeout counter msg
= ioMethod>>=gogo retries timeout counter-1
I do not know how to model this last condition/line.
P.S I am not yet familiar with threading in Haskell (beginner here) and I do think that the timeout-ed scope should perform in different thread,and somehow I need to check it from my main program, and either recall it (if retries>0) or end the main method.
You can use timeout to add a timeout to any blocking call, and simple recursion for retries:
retry :: Int -> Int -> IO a -> IO (Maybe a)
retry 0 _ _ = return Nothing
retry numRetries microseconds action = do
result <- timeout microseconds action
case result of
Nothing -> retry (numRetries-1) microseconds action
Just a -> return (Just a)
Do read the documentation for caveats about FFI stuff, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With