Skip to content

Commit

Permalink
Use a default parameter value to set ContinuousClock as the default…
Browse files Browse the repository at this point in the history
… clock rather than using a separate method.
  • Loading branch information
fumoboy007 committed Jan 16, 2024
1 parent 9f13348 commit 9edd186
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 128 deletions.
52 changes: 2 additions & 50 deletions Sources/Retry/RetryConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,6 @@ public struct RetryConfiguration<ClockType: Clock> {
public var recoverFromFailure: @Sendable (any Error) -> RecoveryAction<ClockType>

#if canImport(OSLog)
/// Configures the retry behavior when the clock type is `ContinuousClock`.
///
/// - Parameters:
/// - maxAttempts: The maximum number of times to attempt the operation. Must be greater than `0`.
/// - backoff: The choice of algorithm that will be used to determine how long to sleep in between attempts.
/// - appleLogger: The logger that will be used to log a message when an attempt fails. The function will
/// log messages using the `debug` log level.
/// - logger: The logger that will be used to log a message when an attempt fails. The function will log
/// messages using the `debug` log level. Consider using `appleLogger` when possible.
/// - recoverFromFailure: A closure that determines what action to take, given the error that was thrown.
/// The closure will not be called if the error is ``Retryable`` or ``NotRetryable``.
public init(
maxAttempts: Int? = 3,
backoff: Backoff<ContinuousClock> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
appleLogger: os.Logger? = nil,
logger: Logging.Logger? = nil,
recoverFromFailure: @escaping @Sendable (any Error) -> RecoveryAction<ContinuousClock> = { _ in .retry }
) where ClockType == ContinuousClock {
self.init(maxAttempts: maxAttempts,
clock: ContinuousClock(),
backoff: backoff,
appleLogger: appleLogger,
logger: logger,
recoverFromFailure: recoverFromFailure)
}

/// Configures the retry behavior when the clock’s duration type is the standard `Duration` type.
///
/// - Parameters:
Expand All @@ -95,7 +69,7 @@ public struct RetryConfiguration<ClockType: Clock> {
/// The closure will not be called if the error is ``Retryable`` or ``NotRetryable``.
public init(
maxAttempts: Int? = 3,
clock: ClockType,
clock: ClockType = ContinuousClock(),
backoff: Backoff<ClockType> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
appleLogger: os.Logger? = nil,
logger: Logging.Logger? = nil,
Expand Down Expand Up @@ -151,28 +125,6 @@ public struct RetryConfiguration<ClockType: Clock> {
self.recoverFromFailure = recoverFromFailure
}
#else
/// Configures the retry behavior when the clock type is `ContinuousClock`.
///
/// - Parameters:
/// - maxAttempts: The maximum number of times to attempt the operation. Must be greater than `0`.
/// - backoff: The choice of algorithm that will be used to determine how long to sleep in between attempts.
/// - logger: The logger that will be used to log a message when an attempt fails. The function will log
/// messages using the `debug` log level.
/// - recoverFromFailure: A closure that determines what action to take, given the error that was thrown.
/// The closure will not be called if the error is ``Retryable`` or ``NotRetryable``.
public init(
maxAttempts: Int? = 3,
backoff: Backoff<ContinuousClock> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
logger: Logging.Logger? = nil,
recoverFromFailure: @escaping @Sendable (any Error) -> RecoveryAction<ContinuousClock> = { _ in .retry }
) where ClockType == ContinuousClock {
self.init(maxAttempts: maxAttempts,
clock: ContinuousClock(),
backoff: backoff,
logger: logger,
recoverFromFailure: recoverFromFailure)
}

/// Configures the retry behavior when the clock’s duration type is the standard `Duration` type.
///
/// - Parameters:
Expand All @@ -185,7 +137,7 @@ public struct RetryConfiguration<ClockType: Clock> {
/// The closure will not be called if the error is ``Retryable`` or ``NotRetryable``.
public init(
maxAttempts: Int? = 3,
clock: ClockType,
clock: ClockType = ContinuousClock(),
backoff: Backoff<ClockType> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
logger: Logging.Logger? = nil,
recoverFromFailure: @escaping @Sendable (any Error) -> RecoveryAction<ClockType> = { _ in .retry }
Expand Down
80 changes: 2 additions & 78 deletions Sources/Retry/RetryableRequest/RetryableRequest+SafeRetry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,46 +27,6 @@ import OSLog

extension RetryableRequest {
#if canImport(OSLog)
/// Attempts the given operation until it succeeds or until the failure is no longer retryable.
/// Sleeps in between attempts using `ContinuousClock`.
///
/// Failures may not be retryable for the following reasons:
/// - The response indicates that the failure is not transient.
/// - `recoverFromFailure` returns ``RecoveryAction/throw``.
/// - The thrown error is ``NotRetryable``.
/// - The number of attempts reached `maxAttempts`.
///
/// - Precondition: ``isIdempotent`` must return `true`.
///
/// - Parameters:
/// - maxAttempts: The maximum number of times to attempt the operation. Must be greater than `0`.
/// - backoff: The choice of algorithm that will be used to determine how long to sleep in between attempts.
/// - appleLogger: The logger that will be used to log a message when an attempt fails. The function will
/// log messages using the `debug` log level.
/// - logger: The logger that will be used to log a message when an attempt fails. The function will log
/// messages using the `debug` log level. Consider using `appleLogger` when possible.
/// - operation: Attempts the given request.
/// - recoverFromFailure: A closure that determines what action to take, given the error that was thrown.
/// The closure will not be called if the error is ``Retryable`` or ``NotRetryable``.
///
/// - SeeAlso: ``retry(with:operation:)``
public func retry<ReturnType>(
maxAttempts: Int? = 3,
backoff: Backoff<ContinuousClock> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
appleLogger: os.Logger? = nil,
logger: Logging.Logger? = nil,
@_inheritActorContext @_implicitSelfCapture operation: (Self) async throws -> ReturnType,
recoverFromFailure: @escaping @Sendable (any Error) -> RecoveryAction<ContinuousClock> = { _ in .retry }
) async throws -> ReturnType {
return try await retry(maxAttempts: maxAttempts,
clock: ContinuousClock(),
backoff: backoff,
appleLogger: appleLogger,
logger: logger,
operation: operation,
recoverFromFailure: recoverFromFailure)
}

/// Attempts the given operation until it succeeds or until the failure is no longer retryable.
/// Sleeps in between attempts using the given clock whose duration type is the standard `Duration` type.
///
Expand All @@ -93,7 +53,7 @@ extension RetryableRequest {
/// - SeeAlso: ``retry(with:operation:)``
public func retry<ClockType, ReturnType>(
maxAttempts: Int? = 3,
clock: ClockType,
clock: ClockType = ContinuousClock(),
backoff: Backoff<ClockType> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
appleLogger: os.Logger? = nil,
logger: Logging.Logger? = nil,
Expand Down Expand Up @@ -155,42 +115,6 @@ extension RetryableRequest {
operation: operation)
}
#else
/// Attempts the given operation until it succeeds or until the failure is no longer retryable.
/// Sleeps in between attempts using `ContinuousClock`.
///
/// Failures may not be retryable for the following reasons:
/// - The response indicates that the failure is not transient.
/// - `recoverFromFailure` returns ``RecoveryAction/throw``.
/// - The thrown error is ``NotRetryable``.
/// - The number of attempts reached `maxAttempts`.
///
/// - Precondition: ``isIdempotent`` must return `true`.
///
/// - Parameters:
/// - maxAttempts: The maximum number of times to attempt the operation. Must be greater than `0`.
/// - backoff: The choice of algorithm that will be used to determine how long to sleep in between attempts.
/// - logger: The logger that will be used to log a message when an attempt fails. The function will log
/// messages using the `debug` log level.
/// - operation: Attempts the given request.
/// - recoverFromFailure: A closure that determines what action to take, given the error that was thrown.
/// The closure will not be called if the error is ``Retryable`` or ``NotRetryable``.
///
/// - SeeAlso: ``retry(with:operation:)``
public func retry<ReturnType>(
maxAttempts: Int? = 3,
backoff: Backoff<ContinuousClock> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
logger: Logging.Logger? = nil,
@_inheritActorContext @_implicitSelfCapture operation: (Self) async throws -> ReturnType,
recoverFromFailure: @escaping @Sendable (any Error) -> RecoveryAction<ContinuousClock> = { _ in .retry }
) async throws -> ReturnType {
return try await retry(maxAttempts: maxAttempts,
clock: ContinuousClock(),
backoff: backoff,
logger: logger,
operation: operation,
recoverFromFailure: recoverFromFailure)
}

/// Attempts the given operation until it succeeds or until the failure is no longer retryable.
/// Sleeps in between attempts using the given clock whose duration type is the standard `Duration` type.
///
Expand All @@ -215,7 +139,7 @@ extension RetryableRequest {
/// - SeeAlso: ``retry(with:operation:)``
public func retry<ClockType, ReturnType>(
maxAttempts: Int? = 3,
clock: ClockType,
clock: ClockType = ContinuousClock(),
backoff: Backoff<ClockType> = .default(baseDelay: .seconds(1), maxDelay: .seconds(20)),
logger: Logging.Logger? = nil,
@_inheritActorContext @_implicitSelfCapture operation: (Self) async throws -> ReturnType,
Expand Down

0 comments on commit 9edd186

Please sign in to comment.