@@ -17,11 +17,10 @@ public protocol BackoffStrategy<Duration> {
17
17
}
18
18
19
19
@available ( iOS 16 . 0 , macCatalyst 16 . 0 , macOS 13 . 0 , tvOS 16 . 0 , visionOS 1 . 0 , watchOS 9 . 0 , * )
20
- @usableFromInline
21
- struct ConstantBackoffStrategy < Duration: DurationProtocol > : BackoffStrategy {
20
+ @usableFromInline struct ConstantBackoffStrategy < Duration: DurationProtocol > : BackoffStrategy {
22
21
@usableFromInline let constant : Duration
23
22
@usableFromInline init ( constant: Duration ) {
24
- precondition ( constant >= . zero, " Constsnt must be greater than or equal to 0" )
23
+ precondition ( constant >= . zero, " Constant must be greater than or equal to 0" )
25
24
self . constant = constant
26
25
}
27
26
@inlinable func nextDuration( ) -> Duration {
@@ -30,8 +29,7 @@ struct ConstantBackoffStrategy<Duration: DurationProtocol>: BackoffStrategy {
30
29
}
31
30
32
31
@available ( iOS 16 . 0 , macCatalyst 16 . 0 , macOS 13 . 0 , tvOS 16 . 0 , visionOS 1 . 0 , watchOS 9 . 0 , * )
33
- @usableFromInline
34
- struct LinearBackoffStrategy < Duration: DurationProtocol > : BackoffStrategy {
32
+ @usableFromInline struct LinearBackoffStrategy < Duration: DurationProtocol > : BackoffStrategy {
35
33
@usableFromInline var current : Duration
36
34
@usableFromInline let increment : Duration
37
35
@usableFromInline init ( increment: Duration , initial: Duration ) {
@@ -63,8 +61,7 @@ struct LinearBackoffStrategy<Duration: DurationProtocol>: BackoffStrategy {
63
61
}
64
62
65
63
@available ( iOS 16 . 0 , macCatalyst 16 . 0 , macOS 13 . 0 , tvOS 16 . 0 , visionOS 1 . 0 , watchOS 9 . 0 , * )
66
- @usableFromInline
67
- struct MinimumBackoffStrategy < Base: BackoffStrategy > : BackoffStrategy {
64
+ @usableFromInline struct MinimumBackoffStrategy < Base: BackoffStrategy > : BackoffStrategy {
68
65
@usableFromInline var base : Base
69
66
@usableFromInline let minimum : Base . Duration
70
67
@usableFromInline init ( base: Base , minimum: Base . Duration ) {
@@ -77,8 +74,7 @@ struct MinimumBackoffStrategy<Base: BackoffStrategy>: BackoffStrategy {
77
74
}
78
75
79
76
@available ( iOS 16 . 0 , macCatalyst 16 . 0 , macOS 13 . 0 , tvOS 16 . 0 , visionOS 1 . 0 , watchOS 9 . 0 , * )
80
- @usableFromInline
81
- struct MaximumBackoffStrategy < Base: BackoffStrategy > : BackoffStrategy {
77
+ @usableFromInline struct MaximumBackoffStrategy < Base: BackoffStrategy > : BackoffStrategy {
82
78
@usableFromInline var base : Base
83
79
@usableFromInline let maximum : Base . Duration
84
80
@usableFromInline init ( base: Base , maximum: Base . Duration ) {
@@ -91,22 +87,20 @@ struct MaximumBackoffStrategy<Base: BackoffStrategy>: BackoffStrategy {
91
87
}
92
88
93
89
@available ( iOS 18 . 0 , macCatalyst 18 . 0 , macOS 15 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , watchOS 11 . 0 , * )
94
- @usableFromInline
95
- struct FullJitterBackoffStrategy < Base: BackoffStrategy , RNG: RandomNumberGenerator > : BackoffStrategy where Base. Duration == Swift . Duration {
90
+ @usableFromInline struct FullJitterBackoffStrategy < Base: BackoffStrategy , RNG: RandomNumberGenerator > : BackoffStrategy where Base. Duration == Swift . Duration {
96
91
@usableFromInline var base : Base
97
92
@usableFromInline var generator : RNG
98
93
@usableFromInline init ( base: Base , generator: RNG ) {
99
94
self . base = base
100
95
self . generator = generator
101
96
}
102
97
@inlinable mutating func nextDuration( ) -> Base . Duration {
103
- return . init( attoseconds: Int128 . random ( in: 0 ... base. nextDuration ( ) . attoseconds) )
98
+ return . init( attoseconds: Int128 . random ( in: 0 ... base. nextDuration ( ) . attoseconds, using : & generator ) )
104
99
}
105
100
}
106
101
107
102
@available ( iOS 18 . 0 , macCatalyst 18 . 0 , macOS 15 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , watchOS 11 . 0 , * )
108
- @usableFromInline
109
- struct EqualJitterBackoffStrategy < Base: BackoffStrategy , RNG: RandomNumberGenerator > : BackoffStrategy where Base. Duration == Swift . Duration {
103
+ @usableFromInline struct EqualJitterBackoffStrategy < Base: BackoffStrategy , RNG: RandomNumberGenerator > : BackoffStrategy where Base. Duration == Swift . Duration {
110
104
@usableFromInline var base : Base
111
105
@usableFromInline var generator : RNG
112
106
@usableFromInline init ( base: Base , generator: RNG ) {
@@ -120,23 +114,22 @@ struct EqualJitterBackoffStrategy<Base: BackoffStrategy, RNG: RandomNumberGenera
120
114
}
121
115
122
116
@available ( iOS 18 . 0 , macCatalyst 18 . 0 , macOS 15 . 0 , tvOS 18 . 0 , visionOS 2 . 0 , watchOS 11 . 0 , * )
123
- @usableFromInline
124
- struct DecorrelatedJitterBackoffStrategy < Base : BackoffStrategy , RNG : RandomNumberGenerator > : BackoffStrategy where Base . Duration == Swift . Duration {
125
- @usableFromInline var base : Base
117
+ @usableFromInline struct DecorrelatedJitterBackoffStrategy < RNG : RandomNumberGenerator > : BackoffStrategy {
118
+ @ usableFromInline let base : Duration
119
+ @usableFromInline let factor : Int
126
120
@usableFromInline var generator : RNG
127
121
@usableFromInline var current : Duration ?
128
- @usableFromInline let factor : Int
129
- @usableFromInline init ( base: Base , generator: RNG , factor: Int ) {
122
+ @usableFromInline init ( base: Duration , factor: Int , generator: RNG ) {
130
123
precondition ( factor >= 1 , " Factor must be greater than or equal to 1 " )
124
+ precondition ( base >= . zero, " Base must be greater than or equal to 0 " )
131
125
self . base = base
132
126
self . generator = generator
133
127
self . factor = factor
134
128
}
135
- @inlinable mutating func nextDuration( ) -> Base . Duration {
136
- let base = base. nextDuration ( )
137
- let current = current ?? base
138
- let next = Duration ( attoseconds: Int128 . random ( in: base. attoseconds... ( current * factor) . attoseconds, using: & generator) )
139
- self . current = next
129
+ @inlinable mutating func nextDuration( ) -> Duration {
130
+ let previous = current ?? base
131
+ let next = Duration ( attoseconds: Int128 . random ( in: base. attoseconds... ( previous * factor) . attoseconds, using: & generator) )
132
+ current = next
140
133
return next
141
134
}
142
135
}
@@ -161,6 +154,9 @@ public enum Backoff {
161
154
@inlinable public static func exponential( factor: Int , initial: Duration ) -> some BackoffStrategy < Duration > {
162
155
return ExponentialBackoffStrategy ( factor: factor, initial: initial)
163
156
}
157
+ @inlinable public static func decorrelatedJitter< RNG: RandomNumberGenerator > ( factor: Int , base: Duration , using generator: RNG ) -> some BackoffStrategy < Duration > {
158
+ return DecorrelatedJitterBackoffStrategy ( base: base, factor: factor, generator: generator)
159
+ }
164
160
}
165
161
166
162
@available ( iOS 16 . 0 , macCatalyst 16 . 0 , macOS 13 . 0 , tvOS 16 . 0 , visionOS 1 . 0 , watchOS 9 . 0 , * )
@@ -181,7 +177,4 @@ extension BackoffStrategy where Duration == Swift.Duration {
181
177
@inlinable public func equalJitter< RNG: RandomNumberGenerator > ( using generator: RNG = SystemRandomNumberGenerator ( ) ) -> some BackoffStrategy < Duration > {
182
178
return EqualJitterBackoffStrategy ( base: self , generator: generator)
183
179
}
184
- @inlinable public func decorrelatedJitter< RNG: RandomNumberGenerator > ( factor: Int , using generator: RNG = SystemRandomNumberGenerator ( ) ) -> some BackoffStrategy < Duration > {
185
- return DecorrelatedJitterBackoffStrategy ( base: self , generator: generator, factor: factor)
186
- }
187
180
}
0 commit comments