@@ -28,6 +28,7 @@ import Control.Monad
2828import Control.Monad.Catch
2929import Control.Monad.IO.Class
3030import Control.Monad.Reader
31+ import Control.Retry (recovering ,limitRetries )
3132import Control.Applicative
3233import Crypto.Hash
3334import Crypto.Hash.Conduit (sinkHash )
@@ -181,24 +182,6 @@ sinkHashUsing _ = sinkHash
181182hashChecksToZipSink :: MonadThrow m => Request -> [HashCheck ] -> ZipSink ByteString m ()
182183hashChecksToZipSink req = traverse_ (ZipSink . sinkCheckHash req)
183184
184- -- TODO(DanBurton): use Control.Retry instead.
185- -- Type inference drives the decision of which exceptions merit a retry.
186- retry :: (MonadCatch m , Exception e )
187- => Int -- ^ The number of times to retry
188- -> m a -- ^ Action to retry
189- -> m (Either [e ] a )
190- retry n0 action =
191- go n0 []
192- where
193- go n es
194- | n <= 0 = return (Left es)
195- | otherwise = do
196- eRes <- try action
197- case eRes of
198- Left e -> go (n - 1 ) (e : es)
199- Right a -> return (Right a)
200-
201-
202185-- | Copied and extended version of Network.HTTP.Download.download.
203186--
204187-- Has the following additional features:
@@ -223,15 +206,14 @@ verifiedDownload DownloadRequest{..} destpath progressSink = do
223206 liftIO $ whenM' getShouldDownload $ do
224207 createDirectoryIfMissing True dir
225208 withBinaryFile fptmp WriteMode $ \ h -> do
226- eRes <- retry drRetries $
209+ recovering (limitRetries drRetries) [ const $ Handler alwaysRetryHttp] $
227210 flip runReaderT env $
228211 withResponse req (go h)
229- case (eRes :: Either [HttpException ] () ) of
230- Left [] -> throwM $ ZeroTries req
231- Left (e: _) -> throwM e -- just re-throw the latest HttpException
232- Right () -> return ()
233212 renameFile fptmp fp
234213 where
214+ alwaysRetryHttp :: Monad m => HttpException -> m Bool
215+ alwaysRetryHttp _ = return True
216+
235217 whenM' mp m = do
236218 p <- mp
237219 if p then m >> return True else return False
0 commit comments