Sources/Confidence/Http/Retry.swift (38 lines of code) (raw):
import Foundation
enum Retry {
case none
case exponential(maxBackoff: TimeInterval, maxAttempts: UInt)
func handler() -> RetryHandler {
switch self {
case .none:
return NoneRetryHandler()
case let .exponential(maxBackoff, maxAttempts):
return ExponentialBackoffRetryHandler(maxBackoff: maxBackoff, maxAttempts: maxAttempts)
}
}
}
protocol RetryHandler {
func retryIn() -> TimeInterval?
}
class ExponentialBackoffRetryHandler: RetryHandler {
private var currentAttempts: UInt = 0
private let maxBackoff: TimeInterval
private let maxAttempts: UInt
init(maxBackoff: TimeInterval, maxAttempts: UInt) {
self.maxBackoff = maxBackoff
self.maxAttempts = maxAttempts
}
public func retryIn() -> TimeInterval? {
if currentAttempts >= maxAttempts {
return nil
}
let nextRetryTime = min(pow(2, Double(currentAttempts)) + Double.random(in: 0..<1), maxBackoff)
currentAttempts += 1
return nextRetryTime
}
}
class NoneRetryHandler: RetryHandler {
public func retryIn() -> TimeInterval? {
return nil
}
}