Skip to content

Commit

Permalink
feat!: Use Foundation-based HTTP client on Apple platforms (#1282)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbelkins authored Jan 9, 2024
1 parent ed21c50 commit cfa1728
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 32 deletions.
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

0 comments on commit cfa1728

Please sign in to comment.