PadXcode-iPad/Validation/RetryPolicy.swift

32 lines
1.2 KiB
Swift
Raw Normal View History

2026-04-12 00:46:30 -07:00
import Foundation
struct RetryPolicy {
let maxAttempts: Int
let baseDelay: TimeInterval
let maxDelay: TimeInterval
let shouldRetry: (Error) -> Bool
static let fileSave = RetryPolicy(maxAttempts: 4, baseDelay: 0.25, maxDelay: 4.0) { _ in true }
static let network = RetryPolicy(maxAttempts: 3, baseDelay: 0.5, maxDelay: 8.0) { error in
let retryable: Set<Int> = [NSURLErrorTimedOut, NSURLErrorNetworkConnectionLost,
NSURLErrorNotConnectedToInternet, NSURLErrorCannotConnectToHost]
return retryable.contains((error as NSError).code)
}
}
func withRetry<T>(policy: RetryPolicy, operation: @escaping () async throws -> T) async throws -> T {
var lastError: Error?
var delay = policy.baseDelay
for attempt in 1...policy.maxAttempts {
do { return try await operation() }
catch {
lastError = error
guard policy.shouldRetry(error), attempt < policy.maxAttempts else { break }
let jitter = Double.random(in: 0...0.3) * delay
try? await Task.sleep(for: .seconds(min(delay + jitter, policy.maxDelay)))
delay = min(delay * 2, policy.maxDelay)
}
}
throw lastError ?? URLError(.unknown)
}