如何在超时时重试http请求?

时间:2015-04-03 12:04:51

标签: haskell httprequest

我的下载方法经常有超时,我想在这里添加一些重试:

withSocketsDo $ do
    irequest  ← liftIO $ parseUrl url
    fileExist ← doesFileExist fname
    when fileExist $ do
        putStrLn " -> Removing old version"
        removeFile fname
    withManager $ \manager → do
        let request = irequest
             { method = methodGet
             , responseTimeout = Just 10000000 }
        response ← http request manager
        responseBody response C.$$+- sinkFile fname

我找到了ScopedTypeVariables

的方法
retryOnTimeout ∷ IO a → IO a
retryOnTimeout action = catch action $ \ (_ :: HttpException) → do
    putStrLn "Timed out. Trying again."
    threadDelay 5000000
    action

添加尝试计数不是大问题,但似乎我不能只使用类似的东西

response ← retryOnTimeout ( http request manager )

因为它会导致奇怪的类型冲突

Couldn't match type `IO'
              with `resourcet-1.1.3.3:Control.Monad.Trans.Resource.Internal.ResourceT
                      IO'
Expected type: resourcet-1.1.3.3:Control.Monad.Trans.Resource.Internal.ResourceT
                 IO
                 (Network.HTTP.Conduit.Response
                    (C.ResumableSource IO Data.ByteString.Internal.ByteString))
  Actual type: IO
                 (Network.HTTP.Conduit.Response
                    (C.ResumableSource IO Data.ByteString.Internal.ByteString))

如何在HTTP get方法的Timeout上实现重试?

1 个答案:

答案 0 :(得分:1)

错误消息告诉您,您的代码需要IO a,但实际上是ResourceT IO a。最简单的事情是:

  • 更改您的类型签名以匹配
  • 使用catch Control.Exception.Lifted包中的lifted-base代替Control.Exception