-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: Create retry modules #710
Changes from all commits
0296c29
3933cca
8dde8fc
5389c3a
4b6f781
0689ecb
07140b0
41e42aa
94faf27
2ee40f1
846046d
7a5707c
104e462
750152a
9543c67
c6273ac
045d75b
93c5567
4e1d8a9
ac0129a
990d3b0
af83cff
457d932
db8c984
7af28e6
6ce9ab8
2236bc1
f4f8342
cdbfcb8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,8 @@ let package = Package( | |
], | ||
products: [ | ||
.library(name: "ClientRuntime", targets: ["ClientRuntime"]), | ||
.library(name: "SmithyRetriesAPI", targets: ["SmithyRetriesAPI"]), | ||
.library(name: "SmithyRetries", targets: ["SmithyRetries"]), | ||
.library(name: "SmithyReadWrite", targets: ["SmithyReadWrite"]), | ||
.library(name: "SmithyXML", targets: ["SmithyXML"]), | ||
.library(name: "SmithyJSON", targets: ["SmithyJSON"]), | ||
|
@@ -43,6 +45,8 @@ let package = Package( | |
.target( | ||
name: "ClientRuntime", | ||
dependencies: [ | ||
"SmithyRetriesAPI", | ||
"SmithyRetries", | ||
"SmithyXML", | ||
"SmithyJSON", | ||
"SmithyFormURL", | ||
|
@@ -53,6 +57,19 @@ let package = Package( | |
.copy("PrivacyInfo.xcprivacy") | ||
] | ||
), | ||
.target( | ||
name: "SmithyRetriesAPI" | ||
), | ||
.target( | ||
name: "SmithyRetries", | ||
dependencies: [ | ||
.product(name: "AwsCommonRuntimeKit", package: "aws-crt-swift"), | ||
] | ||
), | ||
.testTarget( | ||
name: "SmithyRetriesTests", | ||
dependencies: ["ClientRuntime", "SmithyRetriesAPI", "SmithyRetries"] | ||
), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Create Swift targets for
|
||
.target( | ||
name: "SmithyReadWrite", | ||
dependencies: [ | ||
|
@@ -121,11 +138,11 @@ func addTestServiceTargets() { | |
package.targets += [ | ||
.target( | ||
name: "WeatherSDK", | ||
dependencies: ["SmithyTestUtil", "ClientRuntime"] | ||
dependencies: ["SmithyTestUtil", "ClientRuntime", "SmithyRetriesAPI", "SmithyRetries"] | ||
), | ||
.testTarget( | ||
name: "WeatherSDKTests", | ||
dependencies: ["WeatherSDK"] | ||
dependencies: ["WeatherSDK", "SmithyTestUtil"] | ||
) | ||
] | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,8 @@ | |
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
import struct SmithyRetriesAPI.RetryStrategyOptions | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separate imports have to be added in many files for the retry types extracted into modules. |
||
public protocol DefaultClientConfiguration: ClientConfiguration { | ||
/// The configuration for retry of failed network requests. | ||
/// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,12 @@ | |
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
import protocol SmithyRetriesAPI.RetryStrategy | ||
import protocol SmithyRetriesAPI.RetryErrorInfoProvider | ||
import struct SmithyRetriesAPI.RetryStrategyOptions | ||
import struct SmithyRetries.DefaultRetryStrategy | ||
import struct SmithyRetries.ExponentialBackoffStrategy | ||
|
||
/// Provides configuration options for a Smithy-based service. | ||
public struct DefaultSDKRuntimeConfiguration<DefaultSDKRuntimeRetryStrategy: RetryStrategy, | ||
DefaultSDKRuntimeRetryErrorInfoProvider: RetryErrorInfoProvider> { | ||
|
@@ -80,7 +86,7 @@ | |
static func makeClient( | ||
httpClientConfiguration: HttpClientConfiguration = defaultHttpClientConfiguration | ||
) -> HTTPClient { | ||
#if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) || os(macOS) | ||
Check warning on line 89 in Sources/ClientRuntime/Config/DefaultSDKRuntimeConfiguration.swift GitHub Actions / downstream (macos-13-xlarge, Xcode_14.1, platform=OS X)
Check warning on line 89 in Sources/ClientRuntime/Config/DefaultSDKRuntimeConfiguration.swift GitHub Actions / downstream (macos-13-xlarge, Xcode_14.1, platform=OS X)
Check warning on line 89 in Sources/ClientRuntime/Config/DefaultSDKRuntimeConfiguration.swift GitHub Actions / downstream (macos-13-xlarge, Xcode_14.1, platform=tvOS Simulator,OS=16.1,name=Apple TV 4K (3rd ge...
Check warning on line 89 in Sources/ClientRuntime/Config/DefaultSDKRuntimeConfiguration.swift GitHub Actions / downstream (macos-13-xlarge, Xcode_14.1, platform=iOS Simulator,OS=16.1,name=iPhone 14)
|
||
return URLSessionHTTPClient(httpClientConfiguration: httpClientConfiguration) | ||
#else | ||
let connectTimeoutMs = httpClientConfiguration.connectTimeout.map { UInt32($0 * 1000) } | ||
|
@@ -107,7 +113,9 @@ | |
/// The retry strategy options to use when none is provided. | ||
/// | ||
/// Defaults to options with the defaults defined in `RetryStrategyOptions`. | ||
static var defaultRetryStrategyOptions: RetryStrategyOptions { RetryStrategyOptions() } | ||
static var defaultRetryStrategyOptions: RetryStrategyOptions { | ||
RetryStrategyOptions(backoffStrategy: ExponentialBackoffStrategy()) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since |
||
|
||
/// The log mode to use when none is provided | ||
/// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
public extension DefaultRetryStrategy { | ||
|
||
/// Errors that may be thrown when an operation is retried unsuccessfully. | ||
enum Error: Swift.Error { | ||
|
||
/// The number and frequency of retries being attempted has exceeded the | ||
/// current limits. | ||
/// | ||
/// This error is only raised when the `adaptive` rate limiting mode of retry is used. | ||
case insufficientQuota | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,10 @@ | |
// | ||
|
||
import struct Foundation.TimeInterval | ||
import protocol SmithyRetriesAPI.RetryStrategy | ||
import struct SmithyRetriesAPI.RetryStrategyOptions | ||
import struct SmithyRetriesAPI.RetryErrorInfo | ||
import enum SmithyRetriesAPI.RetryError | ||
|
||
public struct DefaultRetryStrategy: RetryStrategy { | ||
public typealias Token = DefaultRetryToken | ||
|
@@ -43,7 +47,7 @@ public struct DefaultRetryStrategy: RetryStrategy { | |
if let capacityAmount = await tokenToRenew.quota.hasRetryQuota(isTimeout: errorInfo.isTimeout) { | ||
tokenToRenew.capacityAmount = capacityAmount | ||
} else { | ||
throw RetryError.insufficientQuota | ||
throw Error.insufficientQuota | ||
} | ||
let isThrottling = errorInfo.errorType == .throttling | ||
await tokenToRenew.quota.updateClientSendingRate(isThrottling: isThrottling) | ||
|
@@ -55,8 +59,3 @@ public struct DefaultRetryStrategy: RetryStrategy { | |
await token.quota.retryQuotaRelease(isSuccess: true, capacityAmount: token.capacityAmount) | ||
} | ||
} | ||
|
||
enum RetryError: Error { | ||
case maxAttemptsReached | ||
case insufficientQuota | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error was made public and moved to its own file in |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
import enum SmithyRetriesAPI.RetryErrorType | ||
import AwsCommonRuntimeKit | ||
|
||
public extension RetryErrorType { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This extension was split from the declaration of This extension goes into the implementation module SmithyRetries since it is dependent on CRT. |
||
|
||
func toCRTType() -> AwsCommonRuntimeKit.RetryError { | ||
switch self { | ||
case .transient: return .transient | ||
case .throttling: return .throttling | ||
case .serverError: return .serverError | ||
case .clientError: return .clientError | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
/// Errors that may be thrown when an operation is retried unsuccessfully. | ||
public enum RetryError: Error { | ||
|
||
/// The maximum number of allowed retry attempts were made, | ||
/// but the operation could not be successfully completed. | ||
case maxAttemptsReached | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This type was originally declared along with the Now, it's public and in the SmithyRetriesAPI module. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this actually used by/part of SmithyRetriesAPI? I don't see mention of the 'quota' concept anywhere in API, but it is here (unless I've missed something). I also don't see it used anywhere, presumably its meant to be the type of error that could be thrown by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, might be a good time to add some more swift docs on what each of these types are, what they do, etc. (in general, not just for |
milesziemer marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,11 @@ | |
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
import AwsCommonRuntimeKit | ||
|
||
/// This enum is a general classification that is assigned to errors that resulted from a failed attempt to perform | ||
/// an operation. | ||
/// | ||
/// The retry strategy uses this classification to decide whether and when to retry a failed attempt. | ||
public enum RetryErrorType: Equatable { | ||
|
||
/// This is a connection level error such as a socket timeout, socket connect error, tls negotiation timeout etc... | ||
|
@@ -22,15 +25,3 @@ public enum RetryErrorType: Equatable { | |
/// Doesn’t count against any budgets. This could be something like a 401 challenge in HTTP. | ||
case clientError | ||
} | ||
|
||
public extension RetryErrorType { | ||
|
||
func toCRTType() -> AwsCommonRuntimeKit.RetryError { | ||
switch self { | ||
case .transient: return .transient | ||
case .throttling: return .throttling | ||
case .serverError: return .serverError | ||
case .clientError: return .clientError | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This CRT-dependent extension was split off to its own file in SmithyRetries (see above.) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,12 +36,12 @@ public struct RetryStrategyOptions { | |
/// Sets the initial available capacity for this retry strategy's quotas. | ||
/// | ||
/// Used only during testing, production uses the default values. | ||
let availableCapacity: Int | ||
public let availableCapacity: Int | ||
|
||
/// Sets the maximum capacity for this retry strategy's quotas. | ||
/// | ||
/// Used only during testing, production uses the default values. | ||
let maxCapacity: Int | ||
public let maxCapacity: Int | ||
|
||
/// Creates a new set of retry strategy options | ||
/// - Parameters: | ||
|
@@ -50,7 +50,7 @@ public struct RetryStrategyOptions { | |
/// - availableCapacity: The number of available tokens in a retry quota. Defaults to 500. | ||
/// - maxCapacity: The max number of tokens in a retry quota. Defaults to 500. | ||
public init( | ||
backoffStrategy: RetryBackoffStrategy = ExponentialBackoffStrategy(), | ||
backoffStrategy: RetryBackoffStrategy, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
maxRetriesBase: Int = 2, | ||
availableCapacity: Int = 500, | ||
maxCapacity: Int = 500, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to list these test exceptions to lint rules 1 by 1