{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-} module Distribution.Skete.DownloadUtils ( cachelessGet, cachingGet, retryingHTTP ) where import qualified Data.ByteString.Lazy as BSL import Control.DeepSeq import Control.Monad.Catch (MonadCatch) import qualified Control.Monad.Catch as E import Control.Lens import Control.Monad.Log (MonadLog) import qualified Control.Monad.Log as Log import Control.Monad.Trans import Data.Text (Text) import qualified Data.Text as T import Network.HTTP.Client (HttpException) import Network.Wreq import qualified System.IO.Error as IOE retryingHTTP :: (MonadIO m, MonadCatch m, MonadLog env m) => Int -> m BSL.ByteString -> m BSL.ByteString retryingHTTP 1 r = r retryingHTTP c r = E.catch r (\(_::HttpException) -> do Log.info . mconcat $ ["HTTP failed and retying ", T.pack (show c)] retryingHTTP (c-1) r) cachingGet :: (MonadIO m, MonadCatch m, MonadLog env m) => FilePath -> Text -> m BSL.ByteString cachingGet cf uri = do Log.debug . mconcat $ ["cachingGet of ", uri, " with ", T.pack cf] f <- E.catchJust (\e -> if IOE.isDoesNotExistErrorType (IOE.ioeGetErrorType e) then Just () else Nothing) (do cfc <- liftIO $ BSL.readFile cf Log.debug . mconcat $ ["Got ", uri, " from disk cache"] return cfc) $ \_ -> do Log.debug . mconcat $ ["Cache lacked ", T.pack cf] t <- liftIO $ (^. responseBody) <$> get (T.unpack uri) Log.debug . mconcat $ ["Got ", uri, " from the network"] liftIO $ BSL.writeFile cf t Log.debug . mconcat $ ["Wrote ", uri, " to ", T.pack cf] return t f `deepseq` return f cachelessGet :: (MonadIO m, MonadLog env m) => Text -> m BSL.ByteString cachelessGet uri = do Log.debug . mconcat $ ["cachelessGet of ", uri] t <- liftIO $ (^. responseBody) <$> get (T.unpack uri) Log.debug . mconcat $ ["Got ", uri, " from the network"] return t