Skip to content
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!: Use Foundation-based HTTP client on Apple platforms #1282

Merged
merged 15 commits into from
Jan 9, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ class AWSMediaConvertTests: XCTestCase {
let input2 = GetJobTemplateInput(name: name)
let output2 = try await client.getJobTemplate(input: input2)

// Verify the name of the retrieved template is the same as the
XCTAssertEqual(output2.jobTemplate?.name, name)
// Verify the name of the created & retrieved templates is the same as the original
XCTAssertEqual(output1.jobTemplate?.name, name)
XCTAssertEqual(output1.jobTemplate?.name, output2.jobTemplate?.name)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import XCTest
import AWSS3
import ClientRuntime
@testable import ClientRuntime

final class S3StreamTests: S3XCTestCase {
let objectName = "hello-world"
Expand Down Expand Up @@ -43,7 +43,7 @@ final class S3StreamTests: S3XCTestCase {
func test_putObject_givenStreamBody() async throws {
let audioURL = Bundle.module.url(forResource: objectName, withExtension: nil)!
let fileHandle = FileHandle(forReadingAtPath: audioURL.relativePath)!
let fileByteStream = try ByteStream.data(try fileHandle.readToEnd() ?? Data())
let fileByteStream = ByteStream.stream(FileStream(fileHandle: fileHandle))
let input = PutObjectInput(body: fileByteStream, bucket: bucketName, key: objectName)
let output = try await client.putObject(input: input)
XCTAssertNotNil(output)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ import AWSTranscribeStreaming
final class TranscribeStreamingTests: XCTestCase {

func testStartStreamTranscription() async throws {

// The heelo-swift.wav resource is an audio file that contains an automated voice
// saying the words "Hello transcribed streaming from Swift S. D. K.".
// It is 2.976 seconds in duration.
let audioURL = Bundle.module.url(forResource: "hello-swift", withExtension: "wav")!
let audioData = try Data(contentsOf: audioURL)

// A delay will be imposed between chunks to keep the audio streaming to the Teranscribe
// service at approximately real-time.
let duration = 2.976
let chunkSize = 4096
let audioDataSize = audioData.count
let dataRate = Double(audioDataSize) / duration
let delay = Double(chunkSize) / dataRate

let client = try TranscribeStreamingClient(region: "us-west-2")

Expand All @@ -26,6 +35,7 @@ final class TranscribeStreamingTests: XCTestCase {
var currentEnd = min(chunkSize, audioDataSize - currentStart)

while currentStart < audioDataSize {
if currentStart != 0 { try await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000)) }
let dataChunk = audioData[currentStart ..< currentEnd]

let audioEvent = TranscribeStreamingClientTypes.AudioStream.audioevent(.init(audioChunk: dataChunk))
Expand Down
32 changes: 12 additions & 20 deletions Sources/Core/AWSClientRuntime/AWSClientConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ public class AWSClientConfiguration<ServiceSpecificConfiguration: AWSServiceSpec
/// If no decoder is provided, one will be provided by the SDK.
public var decoder: ResponseDecoder?

/// The HTTP client engine to be used for HTTP requests.
/// The HTTP client to be used for SDK HTTP requests.
///
/// If none is provided, AWS provides its own HTTP engine for use.
public var httpClientEngine: HttpClientEngine
/// If none is provided, AWS SDK for Swift selects its own HTTP client for use:
/// - On Mac and Linux, a AWS-provided HTTP client is used for the best stability and performance with heavy AWS workloads.
/// - On iOS, tvOS, watchOS, and visionOS, a `URLSession`-based client is used for maximum compatibility and performance on Apple devices.
public var httpClientEngine: HTTPClient

/// Configuration for the HTTP client.
public var httpClientConfiguration: HttpClientConfiguration
Expand Down Expand Up @@ -102,11 +104,6 @@ public class AWSClientConfiguration<ServiceSpecificConfiguration: AWSServiceSpec
/// This structure is custom code-generated for each AWS service.
public var serviceSpecific: ServiceSpecificConfiguration

/// The timeout for a request in milliseconds
///
/// If none is provided the client will use default values based on the platform.
public var connectTimeoutMs: UInt32?

/// Internal designated init
/// All convenience inits should call this.
private init(
Expand All @@ -121,7 +118,7 @@ public class AWSClientConfiguration<ServiceSpecificConfiguration: AWSServiceSpec
_ retryStrategyOptions: RetryStrategyOptions?,
_ appID: String?,
_ awsRetryMode: AWSRetryMode,
_ connectTimeoutMs: UInt32? = nil
_ httpClientConfiguration: HttpClientConfiguration?
) throws {
typealias RuntimeConfigType =
DefaultSDKRuntimeConfiguration<DefaultRetryStrategy, DefaultRetryErrorInfoProvider>
Expand All @@ -134,13 +131,8 @@ public class AWSClientConfiguration<ServiceSpecificConfiguration: AWSServiceSpec
self.useDualStack = useDualStack
self.useFIPS = useFIPS
self.clientLogMode = RuntimeConfigType.defaultClientLogMode
self.connectTimeoutMs = connectTimeoutMs
self.httpClientConfiguration = RuntimeConfigType.defaultHttpClientConfiguration
if let connectTimeoutMs = self.connectTimeoutMs {
self.httpClientEngine = RuntimeConfigType.httpClientEngineWithTimeout(timeoutMs: connectTimeoutMs)
} else {
self.httpClientEngine = RuntimeConfigType.defaultHttpClientEngine
}
self.httpClientConfiguration = httpClientConfiguration ?? RuntimeConfigType.defaultHttpClientConfiguration
self.httpClientEngine = RuntimeConfigType.makeClient(httpClientConfiguration: self.httpClientConfiguration)
self.idempotencyTokenGenerator = RuntimeConfigType.defaultIdempotencyTokenGenerator
self.logger = RuntimeConfigType.defaultLogger(clientName: self.serviceSpecific.clientName)
self.retryStrategyOptions = retryStrategyOptions ?? RuntimeConfigType.defaultRetryStrategyOptions
Expand Down Expand Up @@ -174,7 +166,7 @@ extension AWSClientConfiguration {
retryMode: AWSRetryMode? = nil,
maxAttempts: Int? = nil,
appID: String? = nil,
connectTimeoutMs: UInt32? = nil
httpClientConfiguration: HttpClientConfiguration? = nil
) async throws {
let fileBasedConfig = try await CRTFileBasedConfiguration.makeAsync()
let resolvedRegionResolver = try regionResolver ?? DefaultRegionResolver { _, _ in fileBasedConfig }
Expand Down Expand Up @@ -213,7 +205,7 @@ extension AWSClientConfiguration {
retryStrategyOptions,
resolvedAppID,
resolvedAWSRetryMode,
connectTimeoutMs
httpClientConfiguration
)
}

Expand All @@ -228,7 +220,7 @@ extension AWSClientConfiguration {
retryMode: AWSRetryMode? = nil,
maxAttempts: Int? = nil,
appID: String? = nil,
connectTimeoutMs: UInt32? = nil
httpClientConfiguration: HttpClientConfiguration? = nil
) throws {
let fileBasedConfig = try CRTFileBasedConfiguration.make()
let resolvedCredentialsProvider: CredentialsProviding
Expand Down Expand Up @@ -260,7 +252,7 @@ extension AWSClientConfiguration {
retryStrategyOptions,
resolvedAppID,
resolvedAWSRetryMode,
connectTimeoutMs
httpClientConfiguration
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,6 @@ class AWSClientConfigurationTests: XCTestCase {
let subject = try await Subject(region: region, appID: appID)
XCTAssertEqual(subject.appID, appID)
}

// MARK: - Timeout

func test_sync_configureTimeoutOptionsFromParams() throws {
let customTimeout: UInt32 = 10_000
let subject = try Subject(region: region, connectTimeoutMs: customTimeout)
XCTAssertEqual(subject.connectTimeoutMs, customTimeout)
}
}

struct TestAWSServiceSpecificConfiguration: AWSServiceSpecificConfiguration {
Expand Down
Loading