[Pitch] Retry & Backoff

I've recently updated this proposal since I've initially pitched it. This is the change log:

1. Dropping support of DurationProtocol in linear and exponential backoff

Due to a flaw found by Github user bobergj I made the decision to drop support of DurationProtocol in linear and exponential backoff algorithms and use Duration instead. This also had the side effect, that I had to bump the overall availability of the algorithms of this proposal to AsyncAlgorithms 1.1.

Why?

If you consider this backoff:

 Backoff.exponential(factor: 2, initial: .seconds(5)).maximum(.seconds(120))

... it might seem like the calculation cannot overflow because it is capped at 120 seconds. However, the exponential function will silently keep multiplying each retry which eventually will overflow Duration at some point (in the given example after 64 retries).

One solution to this problem would be to stop multiplying when the maximum has been reached. However this is would only work if we'd bake the concept of "maximum" into the exponential backoff strategy. This has the consequence that every "top level" backoff strategy would have to implement their own version of maximum.

The other solution would be to keep multiplying in exponential backoffs, but detect that it has overflown (by using multipliedReportingOverflow) and then stop multiplying. This has the consequence that, as stated previously, DurationProtocol is not supported, because only Duration exposes such functionality.

2. Dropping decorrelatedJitter
I might've been a bit overambitious in adding backoff strategies. I initially used this resource: Exponential Backoff And Jitter | AWS Architecture Blog as a reference for jitter variants. However, a lot of other retry frameworks of different programming languages do not support such a wide variety of backoff algorithms. Most support constant, exponential and also some form of randomization.

This is why I am dropping support for decorrelatedJitter and also considering dropping equalJitter (but keeping fullJitter) and linear (since exponential backoff seems to be the industry standard for retry scenarios). I am curious, though, what people think about this. Please provide feedback which timing functions or backoff variants you'd like to use or are using currently.

Since there is no precedent of standalone retry-with-backoff in either Apple frameworks or Swift-related frameworks, I feel like this is quite a balance act of not overdoing it / confusing adopters with too many options but also providing enough so most of the use cases can be solved.

2 Likes