如何在超时时重试http请求?
How to retry http request on timeout?
我的下载方法经常超时,我想在这里添加一些重试:
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 方法实现超时重试?
错误消息告诉您,您的代码需要一个 IO a
,但实际上得到的是一个 ResourceT IO a
。最简单的做法是:
- 更改类型签名以匹配
- 使用
Control.Exception.Lifted
中的 catch
(在 lifted-base
包中)而不是 Control.Exception
我的下载方法经常超时,我想在这里添加一些重试:
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 方法实现超时重试?
错误消息告诉您,您的代码需要一个 IO a
,但实际上得到的是一个 ResourceT IO a
。最简单的做法是:
- 更改类型签名以匹配
- 使用
Control.Exception.Lifted
中的catch
(在lifted-base
包中)而不是Control.Exception