Skip to content

Commit 2a6a1f0

Browse files
committed
update
1 parent 86917b6 commit 2a6a1f0

File tree

5 files changed

+96
-101
lines changed

5 files changed

+96
-101
lines changed

Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import PackageDescription
55

66
let package = Package(
77
name: "retry-policy-service",
8-
platforms: [.macOS(.v12), .iOS(.v15), .watchOS(.v8), .tvOS(.v15)],
8+
platforms: [.macOS(.v11), .iOS(.v14), .watchOS(.v8), .tvOS(.v15)],
99
products: [
1010
// Products define the executables and libraries a package produces, and make them visible to other packages.
1111
.library(

Sources/retry-policy-service/RetryIterator.swift

-72
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,79 @@
11
//
2-
// RetryService.swift
3-
//
2+
// RetryIterator.swift
3+
//
44
//
55
// Created by Igor on 06.03.2023.
66
//
77

88
import Foundation
99

1010

11-
/// Generate sequence of time delays between retries depending on retry strategy
12-
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
13-
public struct RetryService: Sequence{
14-
11+
// RetryService Definition and Implementation
12+
@available(iOS 14.0, macOS 11.0, tvOS 15.0, watchOS 8.0, *)
13+
public struct RetryService: Sequence {
14+
1515
/// Default service
1616
static let `default` = RetryService(strategy: .exponential())
1717

1818
/// Retry strategy
1919
public let strategy: Strategy
2020

2121
/// - Parameter strategy: Retry strategy ``RetryService.Strategy``
22-
public init(strategy: Strategy){
22+
public init(strategy: Strategy) {
2323
self.strategy = strategy
2424
}
25-
25+
2626
/// - Returns: Retry delays iterator
2727
public func makeIterator() -> RetryIterator {
2828
return RetryIterator(service: self)
2929
}
30-
}
31-
30+
31+
/// Retry iterator
32+
@available(iOS 14.0, macOS 11.0, tvOS 15.0, watchOS 8.0, *)
33+
public struct RetryIterator: IteratorProtocol {
34+
35+
/// Current amount of retries
36+
public private(set) var retries: UInt = 0
37+
38+
/// Retry strategy
39+
public let strategy: Strategy
40+
41+
/// A time after which stop producing sequence
42+
public let deadline: DispatchTime
3243

44+
/// - Parameter service: Retry service ``RetryService``
45+
init(service: RetryService) {
46+
self.strategy = service.strategy
47+
self.deadline = .now() + strategy.timeout.toDispatchTimeInterval()
48+
}
3349

50+
/// Returns the next delay amount in nanoseconds, or `nil`.
51+
public mutating func next() -> UInt64? {
52+
guard isValid else { return nil }
53+
defer { retries += 1 }
54+
55+
switch strategy {
56+
case .constant(_, let duration, _):
57+
if let value = duration.toDouble() {
58+
let delay = value * 1e+9
59+
return UInt64(delay)
60+
}
61+
case .exponential(_, let multiplier, let duration, _):
62+
if let duration = duration.toDouble() {
63+
let value = duration * pow(multiplier, Double(retries))
64+
let delay = value * 1e+9
65+
return UInt64(delay)
66+
}
67+
}
68+
return nil
69+
}
3470

71+
/// Validate current iteration
72+
var isValid: Bool {
73+
guard deadline >= .now() else { return false }
74+
let max = strategy.maximumRetries
75+
guard max > retries && max != 0 else { return false }
76+
return true
77+
}
78+
}
79+
}

Sources/retry-policy-service/Strategy.swift

+18-17
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,45 @@ import Foundation
1010
public extension RetryService{
1111

1212
/// Retry strategy
13-
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
13+
@available(iOS 14.0, macOS 11.0, tvOS 15.0, watchOS 8.0, *)
1414
enum Strategy {
1515

16-
/// constant delay between retries
16+
/// Constant delay between retries
1717
case constant(
18-
retry : UInt = 5,
18+
retry: UInt = 5,
1919
duration: DispatchTimeInterval = .seconds(2),
2020
timeout: DispatchTimeInterval = .seconds(Int.max)
2121
)
2222

2323
/// Exponential backoff is a strategy in which you increase the delays between retries.
2424
case exponential(
25-
retry : UInt = 3,
25+
retry: UInt = 3,
2626
multiplier: Double = 2.0,
2727
duration: DispatchTimeInterval = .seconds(2),
2828
timeout: DispatchTimeInterval = .seconds(Int.max)
2929
)
3030

3131
/// Max amount of retries
32-
var maximumRetries: UInt{
33-
switch self{
34-
case .constant(let retry, _, _) : return retry
35-
case .exponential(let retry, _, _, _) : return retry
32+
var maximumRetries: UInt {
33+
switch self {
34+
case .constant(let retry, _, _): return retry
35+
case .exponential(let retry, _, _, _): return retry
3636
}
3737
}
3838

39-
/// Duration between retries For .exponential multiply on the amount of the current retries
40-
var duration: DispatchTimeInterval{
41-
switch self{
42-
case .constant(_, let duration, _) : return duration
43-
case .exponential(_, _, let duration, _) : return duration
39+
/// Duration between retries
40+
var duration: DispatchTimeInterval {
41+
switch self {
42+
case .constant(_, let duration, _): return duration
43+
case .exponential(_, _, let duration, _): return duration
4444
}
4545
}
46+
4647
/// Max time before stop iterating
47-
var timeout: DispatchTimeInterval{
48-
switch self{
49-
case .constant(_, _, let timeout) : return timeout
50-
case .exponential(_, _, _, let timeout) : return timeout
48+
var timeout: DispatchTimeInterval {
49+
switch self {
50+
case .constant(_, _, let timeout): return timeout
51+
case .exponential(_, _, _, let timeout): return timeout
5152
}
5253
}
5354
}

Sources/retry-policy-service/ext/DispatchTimeInterval.swift

+22-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
import Foundation
99

10-
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
10+
import Foundation
11+
12+
// DispatchTimeInterval Extension for toDouble method
1113
extension DispatchTimeInterval {
1214

1315
/// Convert to Double
@@ -29,3 +31,22 @@ extension DispatchTimeInterval {
2931
}
3032
}
3133
}
34+
35+
extension DispatchTimeInterval {
36+
func toDispatchTimeInterval() -> DispatchTimeInterval {
37+
switch self {
38+
case .seconds(let value):
39+
return .seconds(value)
40+
case .milliseconds(let value):
41+
return .milliseconds(value)
42+
case .microseconds(let value):
43+
return .microseconds(value)
44+
case .nanoseconds(let value):
45+
return .nanoseconds(value)
46+
case .never:
47+
return .never
48+
@unknown default:
49+
return .never
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)