amazonka-0.0.8: src/Network/AWS/Internal/Retry.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
-- Module : Network.AWS.Internal.Retry
-- Copyright : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
-- 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 <brendan.g.hay@gmail.com>
-- 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."
]