2015-04-03 73 views
1

我在下載方法往往已經超時了,我想在這裏補充一些重試:與ScopedTypeVariables如何在超時時重試http請求?

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

添加試算

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 

我發現方法不是什麼大問題,但似乎就像我不能隨便使用的東西都

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

錯誤消息告訴你,你的代碼需要IO a,但實際上是給出ResourceT IO a。最容易做的事情是:

  • 更改您的類型簽名匹配
  • 使用catchControl.Exception.Lifted(在lifted-base包),而不是從Control.Exception
+0

我應該使用'resourcet'包' ResourceT'? – Cynede 2015-04-07 06:48:59

+0

並使用'liftIO $ putStrLn'運行其他方法超時。再試一次。'' – Cynede 2015-04-07 06:58:53

+0

對於這兩個問題都可以 – 2015-04-07 10:38:51