h$1L/:      !"#$%&'()*+,-./0123456789(Ozgun Ataman BSD3 Ozgun Ataman provisionalNone &8/)retry0Datatype with stats about retries made thus far.retry*Iteration number, where 0 is the first tryretry2Delay incurred so far from retries in microsecondsretry limitedBackoff = exponentialBackoff 50000 <> limitRetries 5 Naturally, > will retry immediately (delay 0) for an unlimited number of retries, forming the identity for the :.The default retry policy  1 implements a constant 50ms delay, up to 5 times: <> retryPolicyDefault = constantDelay 50000 <> limitRetries 50For anything more complex, just define your own  : > myPolicy = retryPolicy $ \ rs -> if rsIterNumber rs > 10 then Just 1000 else Just 10000 Since 0.7. retryDefault retry policyretryApplies a natural transformation to a policy to run a RetryPolicy meant for the monad m in the monad n! provided a transformation from m to n< is available. A common case is if you have a pure policy, RetryPolicyM Identity" and want to use it to govern an IO computation you could write:  purePolicyInIO :: RetryPolicyM Identity -> RetryPolicyM IO purePolicyInIO = natTransformRetryPolicy (pure . runIdentity) retryConvert a boolean answer to the question "Should we retry?" into a .retry>Initial, default retry status. Use fields or lenses to update.retry;Apply policy on status to see what the decision would be. = implies no retry, ? returns updated status.retryApply policy and delay by its amount if it results in a retry. Return updated status.retryHelper for making simplified policies that don't use the monadic context.retry"Retry immediately, but only up to n times.retryAdd an upperbound to a policy such that once the given time-delay amount *per try* has been reached or exceeded, the policy will stop retrying and fail. If you need to stop retrying once *cumulative* delay reaches a time-delay amount, use retryAdd an upperbound to a policy such that once the cumulative delay over all retries has reached or exceeded the given limit, the policy will stop retrying and fail.retry2Implement a constant delay with unlimited retries.retryGrow delay exponentially each iteration. Each delay will increase by a factor of two.retryFullJitter exponential backoff as explained in AWS Architecture Blog article. 7http://www.awsarchitectureblog.com/2015/03/backoff.html$temp = min(cap, base * 2 ** attempt).sleep = temp / 2 + random_between(0, temp / 2)retryImplement Fibonacci backoff.retrySet a time-upperbound for any delays that may be directed by the given policy. This function does not terminate the retrying. The policy `capDelay maxDelay (exponentialBackoff n)` will never stop retrying. It will reach a state where it retries forever with a delay of maxDelay between each one. To get termination you need to use one of the  function variants.retryRetry combinator for actions that don't raise exceptions, but signal in their type the outcome has failed. Examples are the @, A and EitherT monads.Let's write a function that always fails and watch this combinator retry it 5 additional times following the initial run:import Data.Maybe5let f _ = putStrLn "Running action" >> return Nothing:retrying retryPolicyDefault (const $ return . isNothing) fRunning actionRunning actionRunning actionRunning actionRunning actionRunning actionNothingNote how the latest failing result is returned after all retries have been exhausted. retry A variant of % that allows specifying the initial  so that the retrying operation may pick up where it left off in regards to its retry policy.!retrySame as , but with the ability to override the delay of the retry policy based on information obtained after initiation.For example, if the action to run is a HTTP request that turns out to fail with a status code 429 ("too many requests"), the response may contain a "Retry-After" HTTP header which specifies the number of seconds the client should wait until performing the next request. This function allows overriding the delay calculated by the given retry policy with the delay extracted from this header value.#In other words, given an arbitrary   rp, the following invocation will always delay by 1000 microseconds: retryingDynamic rp (\_ _ -> return $ ConsultPolicyOverrideDelay 1000) f Note that a  s decision to not, perform a retry cannot be overridden. Ie. when to stop retrying is always decided by the retry policy, regardless of the returned  value."retry A variant of !% that allows specifying the initial  so that a retrying operation may pick up where it left off in regards to its retry policy.#retryRetry ALL exceptions that may be raised. To be used with caution; this matches the exception on B5. Note that this handler explicitly does not handle C nor D (for versions of base >= 4.7). It is not a good idea to catch async exceptions as it can result in hanging threads and programs. Note that if you just throw an exception to this thread that does not descend from SomeException, recoverAll will not catch it.See how the action below is run once and retried 5 more times before finally failing for good:?let f _ = putStrLn "Running action" >> error "this is an error"recoverAll retryPolicyDefault fRunning actionRunning actionRunning actionRunning actionRunning actionRunning action*** Exception: this is an error$retry A variant of #% that allows specifying the initial  so that a recovering operation may pick up where it left off in regards to its retry policy.%retry5List of pre-made handlers that will skip retries on C and D. Append your handlers to this list as a convenient way to make sure you're not catching async exceptions like user interrupt.&retryRun an action and recover from a raised exception by potentially retrying the action a number of times. Note that if you're going to use a handler for B, you should add explicit cases *earlier* in the list of handlers to reject C and D9, as catching these can cause thread and program hangs. #< already does this for you so if you just plan on catching B, you may as well use #'retry A variant of &% that allows specifying the initial  so that a recovering operation may pick up where it left off in regards to its retry policy.(retry The difference between this and &) is the same as the difference between ! and .)retry A variant of (% that allows specifying the initial  so that a recovering operation may pick up where it left off in regards to its retry policy.*retry A version of & that tries to run the action only a single time. The control will return immediately upon both success and failure. Useful for implementing retry logic in distributed queues and similar external-interfacing systems.+retryHelper function for constructing handler functions of the form required by &.,retry For use with +..retryRun given policy up to N iterations and gather results. In the pair, the Int! is the iteration number and the  Maybe Int is the delay in microseconds./retryRun given policy up to N iterations and pretty print results on the console.retryMaximum number of retries.retry!Time-delay limit in microseconds.retry!Time-delay limit in microseconds.retryBase delay in microsecondsretryBase delay in microsecondsretryBase delay in microsecondsretryBase delay in microsecondsretryA maximum delay in microsecondsretryAn action to check whether the result should be retried. If True, we delay and retry the operation.retry Action to run retryAn action to check whether the result should be retried. If True, we delay and retry the operation.retry Action to run!retryAn action to check whether the result should be retried. The returned ? determines how/if a retry is performed. See documentation on .retry Action to run"retryAn action to check whether the result should be retried. The returned ? determines how/if a retry is performed. See documentation on .retry Action to run&retry Just use   for default settingsretryShould a given exception be retried? Action will be retried if this returns True *and* the policy allows it. This action will be consulted first even if the policy later blocks it.retryAction to perform'retry Just use   for default settingsretryShould a given exception be retried? Action will be retried if this returns True *and* the policy allows it. This action will be consulted first even if the policy later blocks it.retryAction to perform(retry Just use   for default settingsretryShould a given exception be retried? Action will be retried if this returns either  or  *and* the policy allows it. This action will be consulted first even if the policy later blocks it.retryAction to perform)retry Just use   for default settingsretryShould a given exception be retried? Action will be retried if this returns either  or  *and* the policy allows it. This action will be consulted first even if the policy later blocks it.retryAction to perform*retry Just use   for default settingsretryShould a given exception be retried? Action will be retried if this returns True *and* the policy allows it. This action will be consulted first even if the policy later blocks it.retry/Action to run with updated status upon failure.retry+Main action to perform with current status.retryCurrent status of this step+retry(Test for whether action is to be retriedretryHow to report the generated warning message. Boolean is whether it's being retried or crashed.retry Retry number-retryPolicyretryShould an error be retried?retryAction to perform0  !"#$%&'()*+,-./0  !&(*#%+,- "')$./       !"#$%&'()*+,-./0123456789:;<:;=:;>:?@:;A:?B:?C:DE:FG:HI:HJ$retry-0.9.2.0-CwdWjhBbUSt2aC9XF0ri00 Control.Retry RetryStatus rsIterNumberrsCumulativeDelayrsPreviousDelay RetryAction DontRetry ConsultPolicyConsultPolicyOverrideDelay RetryPolicy RetryPolicyMgetRetryPolicyMretryPolicyDefaultnatTransformRetryPolicy toRetryActiondefaultRetryStatus rsIterNumberLrsCumulativeDelayLrsPreviousDelayL applyPolicy applyAndDelay retryPolicy limitRetrieslimitRetriesByDelaylimitRetriesByCumulativeDelay constantDelayexponentialBackofffullJitterBackofffibonacciBackoffcapDelayretryingresumeRetryingretryingDynamicresumeRetryingDynamic recoverAllresumeRecoverAllskipAsyncExceptions recoveringresumeRecoveringrecoveringDynamicresumeRecoveringDynamicstepping logRetries defaultLogMsg retryOnErrorsimulatePolicysimulatePolicyPP$fMonoidRetryPolicyM$fSemigroupRetryPolicyM$fReadRetryStatus$fShowRetryStatus$fEqRetryStatus$fGenericRetryStatus$fReadRetryAction$fShowRetryAction$fEqRetryAction$fGenericRetryActionbaseGHC.BaseMonoidmappend<> GHC.MaybeNothingmemptyJustMaybe Data.EitherEitherGHC.Exception.Type SomeExceptionGHC.IO.ExceptionAsyncExceptionSomeAsyncException