Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ let lint = false
var extraDependencies: [Package.Dependency] = []
var extraPlugins: [Target.PluginUsage] = []
if lint {
extraDependencies = [.package(url: "https://github.com/realm/SwiftLint", exact: "0.52.4")]
extraPlugins = [.plugin(name: "SwiftLintPlugin", package: "SwiftLint")]
extraDependencies = [.package(url: "https://github.com/realm/SwiftLint.git", from: "0.55.1")]
extraPlugins = [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLint")]
}

let package = Package(
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftRetrier/Core/Model/Policies/RetryPolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ import Foundation

public protocol RetryPolicy: Sendable {
func shouldRetry(on attemptFailure: AttemptFailure) -> RetryDecision
func retryDelay(for attemptFailure: AttemptFailure) -> TimeInterval
func policyAfter(attemptFailure: AttemptFailure, delay: TimeInterval) -> any RetryPolicy
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Foundation

public typealias GiveUpCriteria = @Sendable (
_ attemptFailure: AttemptFailure,
_ nestedPolicyDelay: TimeInterval
) -> Bool

public struct GiveUpCriteriaPolicyWrapper: RetryPolicy {

private let wrapped: RetryPolicy
private let giveUpCriteria: GiveUpCriteria

public init(wrapped: RetryPolicy, giveUpCriteria: @escaping GiveUpCriteria) {
self.wrapped = wrapped
self.giveUpCriteria = giveUpCriteria
}

public func shouldRetry(on attemptFailure: AttemptFailure) -> RetryDecision {
return switch wrapped.shouldRetry(on: attemptFailure) {
case .giveUp:
.giveUp
case .retry(let delay):
if giveUpCriteria(attemptFailure, delay) {
.giveUp
} else {
.retry(delay: delay)
}
}
}

public func policyAfter(attemptFailure: AttemptFailure, delay: TimeInterval) -> any RetryPolicy {
GiveUpCriteriaPolicyWrapper(
wrapped: wrapped.policyAfter(attemptFailure: attemptFailure, delay: delay),
giveUpCriteria: giveUpCriteria
)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@ import Foundation

public extension RetryPolicy {

func giveUp(on giveUpCriterium: @escaping @Sendable (AttemptFailure) -> Bool) -> RetryPolicy {
GiveUpOnPolicyWrapper(wrapped: self, giveUpCriterium: giveUpCriterium)
func giveUp(on giveUpCriteria: @escaping GiveUpCriteria) -> RetryPolicy {
GiveUpCriteriaPolicyWrapper(wrapped: self, giveUpCriteria: giveUpCriteria)
}

func giveUpAfter(maxAttempts: UInt) -> RetryPolicy {
GiveUpOnPolicyWrapper(wrapped: self, giveUpCriterium: { $0.index >= maxAttempts - 1})
GiveUpCriteriaPolicyWrapper(wrapped: self) { attempt, _ in
attempt.index >= maxAttempts - 1
}
}

func giveUpAfter(timeout: TimeInterval) -> RetryPolicy {
GiveUpOnPolicyWrapper(wrapped: self, giveUpCriterium: {
let nextAttemptStart = Date().addingTimeInterval(retryDelay(for: $0))
return nextAttemptStart >= $0.trialStart.addingTimeInterval(timeout)
})
GiveUpCriteriaPolicyWrapper(wrapped: self) { attempt, wrappedDelay in
let nextAttemptStart = Date().addingTimeInterval(wrappedDelay)
return nextAttemptStart >= attempt.trialStart.addingTimeInterval(timeout)
}
Comment on lines 15 to +19
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the only reason retryDelay() was introduced.
As RetryPolicy is now considered stateless, there's no need to work around calling shouldRetry() in GiveUpCriteriaPolicyWrapper.

}

func giveUpOnErrors(matching finalErrorCriterium: @escaping @Sendable (Error) -> Bool) -> RetryPolicy {
GiveUpOnPolicyWrapper(wrapped: self, giveUpCriterium: { finalErrorCriterium($0.error) })
func giveUpOnErrors(matching finalErrorCriteria: @escaping @Sendable (Error) -> Bool) -> RetryPolicy {
GiveUpCriteriaPolicyWrapper(wrapped: self) { attempt, _ in
finalErrorCriteria(attempt.error)
}
}
}
8 changes: 4 additions & 4 deletions Sources/SwiftRetrier/DSL/ColdRepeater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public struct ColdRepeater {

public extension ColdRepeater {

func giveUp(on giveUpCriterium: @escaping @Sendable (AttemptFailure) -> Bool) -> ColdRepeater {
let policy = policy.giveUp(on: giveUpCriterium)
func giveUp(on giveUpCriteria: @escaping GiveUpCriteria) -> ColdRepeater {
let policy = policy.giveUp(on: giveUpCriteria)
return ColdRepeater(policy: policy, repeatDelay: repeatDelay, conditionPublisher: conditionPublisher)
}

Expand All @@ -24,8 +24,8 @@ public extension ColdRepeater {
return ColdRepeater(policy: policy, repeatDelay: repeatDelay, conditionPublisher: conditionPublisher)
}

func giveUpOnErrors(matching finalErrorCriterium: @escaping @Sendable (Error) -> Bool) -> ColdRepeater {
let policy = policy.giveUpOnErrors(matching: finalErrorCriterium)
func giveUpOnErrors(matching finalErrorCriteria: @escaping @Sendable (Error) -> Bool) -> ColdRepeater {
let policy = policy.giveUpOnErrors(matching: finalErrorCriteria)
return ColdRepeater(policy: policy, repeatDelay: repeatDelay, conditionPublisher: conditionPublisher)
}

Expand Down
8 changes: 4 additions & 4 deletions Sources/SwiftRetrier/DSL/ColdRetrier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public struct ColdRetrier {

public extension ColdRetrier {

func giveUp(on giveUpCriterium: @escaping @Sendable (AttemptFailure) -> Bool) -> ColdRetrier {
let policy = policy.giveUp(on: giveUpCriterium)
func giveUp(on giveUpCriteria: @escaping GiveUpCriteria) -> ColdRetrier {
let policy = policy.giveUp(on: giveUpCriteria)
return ColdRetrier(policy: policy, conditionPublisher: conditionPublisher)
}

Expand All @@ -23,8 +23,8 @@ public extension ColdRetrier {
return ColdRetrier(policy: policy, conditionPublisher: conditionPublisher)
}

func giveUpOnErrors(matching finalErrorCriterium: @escaping @Sendable (Error) -> Bool) -> ColdRetrier {
let policy = policy.giveUpOnErrors(matching: finalErrorCriterium)
func giveUpOnErrors(matching finalErrorCriteria: @escaping @Sendable (Error) -> Bool) -> ColdRetrier {
let policy = policy.giveUpOnErrors(matching: finalErrorCriteria)
return ColdRetrier(policy: policy, conditionPublisher: conditionPublisher)
}

Expand Down