ur     (Ozgun Ataman <ozgun.ataman@soostone.com>BSD3 Ozgun Ataman provisionalNone  0;HMTDatatype with stats about retries made thus far. The constructor is deliberately not exported to make additional fields easier to add in a backward-compatible manner. To read or modify fields in RetryStatus, use the accessors or lenses below. Note that if you don't want to use lenses, the exported field names can be used for updates: ]> retryStatus { rsIterNumber = newIterNumber } > retryStatus & rsIterNumberL .~ newIterNumber*Iteration number, where 0 is the first try2Delay incurred so far from retries in microseconds<Latest attempt's delay. Will always be Nothing on first run. Simplified  without any use of the monadic context in determining policy. Mostly maintains backwards compatitibility with type signatures pre-0.7.A  is a function that takes an  and possibly returns a delay in microseconds. Iteration numbers start at zero and increase by one on each retry. A *Nothing* return value from the function implies we have reached the retry limit.Please note that  is a 7. You can collapse multiple strategies into one using   or !4. The semantics of this combination are as follows: If either policy returns ", the combined policy returns ". This can be used to inhibit) after a number of retries, for example.If both policies return a delay, the larger delay will be used. This is quite natural when combining multiple policies to achieve a certain effect.Example:VOne can easily define an exponential backoff policy with a limited number of retries: :> limitedBackoff = exponentialBackoff 50 <> limitRetries 5 Naturally, #d will retry immediately (delay 0) for an unlimited number of retries, forming the identity for the .The default under $1 implements a constant 50ms delay, up to 5 times: -> def = constantDelay 50000 <> limitRetries 50For anything more complex, just define your own : X> myPolicy = retryPolicy $ \ rs -> if rsIterNumber n > 10 then Just 1000 else Just 10000 Since 0.7. Initial, default retry status. Exported mostly to allow user code to test their handlers and retry policies. Use fields or lenses to update. ;Apply policy on status to see what the decision would be. " implies no retry, % returns updated status.VApply policy and delay by its amount if it results in a retry. Return updated status.JHelper for making simplified policies that don't use the monadic context."Retry immediately, but only up to n times.Add an upperbound to a policy such that once the given time-delay amount has been reached or exceeded, the policy will stop retrying and fail.2Implement a constant delay with unlimited retries.WGrow delay exponentially each iteration. Each delay will increase by a factor of two.NFullJitter 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)Implement Fibonacci backoff.Set 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 maxDelayD between each one. To get termination you need to use one of the  function variants.~Retry combinator for actions that don't raise exceptions, but signal in their type the outcome has failed. Examples are the &, ' and EitherT monads.zLet'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 def (const $ return . isNothing) fRunning actionRunning actionRunning actionRunning actionRunning actionRunning actionNothingVNote how the latest failing result is returned after all retries have been exhausted.aRetry ALL exceptions that may be raised. To be used with caution; this matches the exception on (5. Note that this handler explicitly does not handle ) nor * (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 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 def fRunning actionRunning actionRunning actionRunning actionRunning actionRunning action*** Exception: this is an errorRun 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 (M, you should add explicit cases *earlier* in the list of handlers to reject ) and *9, as catching these can cause thread and program hangs. < already does this for you so if you just plan on catching (, you may as well ues  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.LHelper function for constructing handler functions of the form required by . For use with .JRun 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.MRun given policy up to N iterations and pretty print results on the console.+Same as , on - but it maxes out at . :: - or / :: - rather than rolling over0Same as 1 on - but it maxes out at . :: - or / :: - rather than rolling over2Same as 3 on - but it maxes out at . :: - or / :: - rather than rolling over4Same as 5 on - but it maxes out at . :: - or MinBound :: - rather than rolling over)67 Maximum number of retries.!Time-delay limit in microseconds.Base delay in microsecondsFirst delay in microsecondsBase delay in microsecondsA maximum delay in microsecondsdAn action to check whether the result should be retried. If True, we delay and retry the operation. Action to run Just use $ for default settingsShould 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.Action to perform Just use $ for default settingsShould 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./Action to run with updated status upon failure.+Main action to perform with current status.Current status of this step(Test for whether action is to be retried_How to report the generated warning message. Boolean is whether it's being retried or crashed. Retry number8+0249:;   #67 8+0249:;<      ! " #$% &'()$*$+,-./01023456789:9;<4=>?@ABCDEFGHIJ retry-0.7.2 Control.Retry RetryStatus rsIterNumberrsCumulativeDelayrsPreviousDelay RetryPolicy RetryPolicyMgetRetryPolicyMdefaultRetryStatus rsIterNumberLrsCumulativeDelayLrsPreviousDelayL applyPolicy applyAndDelay retryPolicy limitRetrieslimitRetriesByDelay constantDelayexponentialBackofffullJitterBackofffibonacciBackoffcapDelayretrying recoverAll recoveringstepping logRetries defaultLogMsgsimulatePolicysimulatePolicyPPbase Data.MonoidMonoidmappend<> Data.MaybeNothingmemptydata-default-class-0.0.1Data.Default.ClassdefJustMaybe Data.EitherEither GHC.Exception SomeExceptionGHC.IO.ExceptionAsyncExceptionSomeAsyncException boundedPlusGHC.Num+ghc-prim GHC.TypesIntGHC.EnummaxBoundminBound boundedMult* boundedSum Data.Listsum boundedPowGHC.Real^Lens'LensppTimelens$fMonoidRetryPolicyM$fDefaultRetryPolicyM