{-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} -- Module : Network.AWS.Internal.Retry -- Copyright : (c) 2013-2014 Brendan Hay -- License : This Source Code Form is subject to the terms of -- the Mozilla Public License, v. 2.0. -- A copy of the MPL can be found in the LICENSE file or -- you can obtain it at http://mozilla.org/MPL/2.0/. -- Maintainer : Brendan Hay -- Stability : experimental -- Portability : non-portable (GHC extensions) module Network.AWS.Internal.Retry ( retrier , waiter ) where import Control.Monad import Control.Monad.IO.Class import Control.Retry import Data.List (intersperse) import Data.Monoid import Network.AWS.Internal.Env import Network.AWS.Internal.Log import Network.AWS.Prelude import Network.AWS.Types import Network.AWS.Waiters retrier :: (MonadIO m, AWSService (Sv a)) => Env -> Request a -> m (Response' a) -> m (Response' a) retrier Env{..} rq = retrying (fromMaybe policy _envRetryPolicy) check where policy = limitRetries _retryAttempts <> RetryPolicy (const $ listToMaybe [0 | not stream]) <> RetryPolicy delay where !stream = isStreaming (_rqBody rq) delay n | n > 0 = Just $ truncate (grow * 1000000) | otherwise = Nothing where grow = _retryBase * (fromIntegral _retryGrowth ^^ (n - 1)) check n = \case Left (ServiceError _ s e) | _retryCheck s e -> msg n >> return True Left (HttpError e) -> do p <- liftIO (_envRetryCheck n e) when p (msg n) >> return p _ -> return False msg n = debug _envLogger $ "[Retrying] after " <> build (n + 1) <> " attempts." Exponential{..} = _svcRetry (serviceOf rq) waiter :: MonadIO m => Env -> Wait a -> Request a -> m (Response' a) -> m (Response' a) waiter Env{..} w@Wait{..} rq = retrying policy check where policy = limitRetries _waitAttempts <> constantDelay (_waitDelay * 1000000) check n rs = do let a = fromMaybe AcceptRetry (accept w rq rs) msg n a >> return (retry a) retry AcceptSuccess = False retry AcceptFailure = False retry AcceptRetry = True msg n a = debug _envLogger . mconcat . intersperse " " $ [ "[Await " <> build _waitName <> "]" , build a , " after " , build (n + 1) , "attempts." ]