Skip to content

Commit 8c542ff

Browse files
authored
refactor: use new coroutine scope and shutdown lifecycle method (#159)
1 parent 870a64b commit 8c542ff

File tree

6 files changed

+25
-35
lines changed

6 files changed

+25
-35
lines changed

client-runtime/auth/common/test/aws/sdk/kotlin/runtime/auth/AwsSigv4SigningMiddlewareTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import aws.sdk.kotlin.runtime.testing.runSuspendTest
1010
import software.aws.clientrt.client.ExecutionContext
1111
import software.aws.clientrt.http.*
1212
import software.aws.clientrt.http.content.ByteArrayContent
13-
import software.aws.clientrt.http.engine.HttpClientEngine
13+
import software.aws.clientrt.http.engine.HttpClientEngineBase
1414
import software.aws.clientrt.http.operation.*
1515
import software.aws.clientrt.http.request.HttpRequest
1616
import software.aws.clientrt.http.request.HttpRequestBuilder
@@ -54,7 +54,7 @@ class AwsSigv4SigningMiddlewareTest {
5454
}
5555

5656
private suspend fun getSignedRequest(operation: SdkHttpOperation<Unit, HttpResponse>): HttpRequest {
57-
val mockEngine = object : HttpClientEngine {
57+
val mockEngine = object : HttpClientEngineBase("test") {
5858
override suspend fun roundTrip(request: HttpRequest): HttpCall {
5959
val now = Instant.now()
6060
val resp = HttpResponse(HttpStatusCode.fromValue(200), Headers.Empty, HttpBody.Empty)

client-runtime/http-client-engine-crt/common/src/aws/sdk/kotlin/runtime/http/engine/crt/CrtHttpEngine.kt

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ import aws.sdk.kotlin.crt.io.*
1111
import kotlinx.coroutines.sync.Mutex
1212
import kotlinx.coroutines.sync.withLock
1313
import software.aws.clientrt.http.engine.HttpClientEngine
14+
import software.aws.clientrt.http.engine.HttpClientEngineBase
1415
import software.aws.clientrt.http.engine.HttpClientEngineConfig
16+
import software.aws.clientrt.http.engine.callContext
1517
import software.aws.clientrt.http.request.HttpRequest
1618
import software.aws.clientrt.http.response.HttpCall
1719
import software.aws.clientrt.time.Instant
18-
import kotlin.coroutines.*
1920

2021
/**
2122
* [HttpClientEngine] based on the AWS Common Runtime HTTP client
2223
*/
23-
public class CrtHttpEngine(public val config: HttpClientEngineConfig) : HttpClientEngine {
24+
public class CrtHttpEngine(public val config: HttpClientEngineConfig) : HttpClientEngineBase("crt") {
2425
// FIXME - use the default TLS context when profile cred provider branch is merged
2526
private val tlsCtx = TlsContext(TlsContextOptions.defaultClient())
2627

@@ -38,12 +39,13 @@ public class CrtHttpEngine(public val config: HttpClientEngineConfig) : HttpClie
3839
private val mutex = Mutex()
3940

4041
override suspend fun roundTrip(request: HttpRequest): HttpCall {
42+
val callContext = callContext()
4143
val manager = getManagerForUri(request.uri)
4244
val conn = manager.acquireConnection()
4345

4446
try {
4547
val reqTime = Instant.now()
46-
val engineRequest = request.toCrtRequest(coroutineContext)
48+
val engineRequest = request.toCrtRequest(callContext)
4749

4850
// LIFETIME: connection will be released back to the pool/manager when
4951
// the response completes OR on exception
@@ -54,7 +56,7 @@ public class CrtHttpEngine(public val config: HttpClientEngineConfig) : HttpClie
5456

5557
val resp = respHandler.waitForResponse()
5658

57-
return HttpCall(request, resp, reqTime, Instant.now())
59+
return HttpCall(request, resp, reqTime, Instant.now(), callContext)
5860
} catch (ex: Exception) {
5961
try {
6062
manager.releaseConnection(conn)
@@ -65,13 +67,10 @@ public class CrtHttpEngine(public val config: HttpClientEngineConfig) : HttpClie
6567
}
6668
}
6769

68-
override fun close() {
70+
override fun shutdown() {
6971
// close all resources
70-
71-
// FIXME - this can go away after we enforce a lifecycle to engines that guarantees when close/shutdown is called
72-
mutex.withLockNoSuspend {
73-
connManagers.forEach { entry -> entry.value.close() }
74-
}
72+
// SAFETY: shutdown is only invoked once AND only after all requests have completed and no more are coming
73+
connManagers.forEach { entry -> entry.value.close() }
7574
tlsCtx.close()
7675
}
7776

@@ -80,13 +79,4 @@ public class CrtHttpEngine(public val config: HttpClientEngineConfig) : HttpClie
8079
HttpClientConnectionManager(options.apply { this.uri = uri }.build())
8180
}
8281
}
83-
84-
private fun <T> Mutex.withLockNoSuspend(block: () -> T): T {
85-
while (!tryLock()) { } // spin
86-
try {
87-
return block()
88-
} finally {
89-
unlock()
90-
}
91-
}
9282
}

client-runtime/protocols/aws-json-protocols/common/test/aws/sdk/kotlin/runtime/protocol/json/AwsJsonProtocolTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import aws.sdk.kotlin.runtime.testing.runSuspendTest
99
import software.aws.clientrt.client.ExecutionContext
1010
import software.aws.clientrt.http.*
1111
import software.aws.clientrt.http.content.ByteArrayContent
12-
import software.aws.clientrt.http.engine.HttpClientEngine
12+
import software.aws.clientrt.http.engine.HttpClientEngineBase
1313
import software.aws.clientrt.http.operation.*
1414
import software.aws.clientrt.http.request.HttpRequest
1515
import software.aws.clientrt.http.request.HttpRequestBuilder
@@ -24,7 +24,7 @@ class AwsJsonProtocolTest {
2424

2525
@Test
2626
fun testSetJsonProtocolHeaders() = runSuspendTest {
27-
val mockEngine = object : HttpClientEngine {
27+
val mockEngine = object : HttpClientEngineBase("test") {
2828
override suspend fun roundTrip(request: HttpRequest): HttpCall {
2929
val resp = HttpResponse(HttpStatusCode.OK, Headers.Empty, HttpBody.Empty)
3030
val now = Instant.now()
@@ -57,7 +57,7 @@ class AwsJsonProtocolTest {
5757

5858
@Test
5959
fun testEmptyBody() = runSuspendTest {
60-
val mockEngine = object : HttpClientEngine {
60+
val mockEngine = object : HttpClientEngineBase("test") {
6161
override suspend fun roundTrip(request: HttpRequest): HttpCall {
6262
val resp = HttpResponse(HttpStatusCode.OK, Headers.Empty, HttpBody.Empty)
6363
val now = Instant.now()
@@ -88,7 +88,7 @@ class AwsJsonProtocolTest {
8888

8989
@Test
9090
fun testDoesNotOverride() = runSuspendTest {
91-
val mockEngine = object : HttpClientEngine {
91+
val mockEngine = object : HttpClientEngineBase("test") {
9292
override suspend fun roundTrip(request: HttpRequest): HttpCall {
9393
val resp = HttpResponse(HttpStatusCode.OK, Headers.Empty, HttpBody.Empty)
9494
val now = Instant.now()

client-runtime/protocols/aws-json-protocols/common/test/aws/sdk/kotlin/runtime/protocol/json/RestJsonErrorTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import software.aws.clientrt.ServiceErrorMetadata
1313
import software.aws.clientrt.client.ExecutionContext
1414
import software.aws.clientrt.http.*
1515
import software.aws.clientrt.http.content.ByteArrayContent
16-
import software.aws.clientrt.http.engine.HttpClientEngine
16+
import software.aws.clientrt.http.engine.HttpClientEngineBase
1717
import software.aws.clientrt.http.operation.HttpDeserialize
1818
import software.aws.clientrt.http.operation.SdkHttpOperation
1919
import software.aws.clientrt.http.operation.UnitDeserializer
@@ -104,7 +104,7 @@ class RestJsonErrorTest {
104104
val body = ByteArrayContent(payload.encodeToByteArray())
105105
val httpResp = HttpResponse(HttpStatusCode.fromValue(502), headers, body)
106106

107-
val mockEngine = object : HttpClientEngine {
107+
val mockEngine = object : HttpClientEngineBase("test") {
108108
override suspend fun roundTrip(request: HttpRequest): HttpCall {
109109
val now = Instant.now()
110110
return HttpCall(request, httpResp, now, now)
@@ -154,7 +154,7 @@ class RestJsonErrorTest {
154154
val body = ByteArrayContent(payload.encodeToByteArray())
155155
val httpResp = HttpResponse(HttpStatusCode.fromValue(502), headers, body)
156156

157-
val mockEngine = object : HttpClientEngine {
157+
val mockEngine = object : HttpClientEngineBase("test") {
158158
override suspend fun roundTrip(request: HttpRequest): HttpCall {
159159
val now = Instant.now()
160160
return HttpCall(request, httpResp, now, now)
@@ -215,7 +215,7 @@ class RestJsonErrorTest {
215215
val body = ByteArrayContent(payload.encodeToByteArray())
216216
val httpResp = HttpResponse(HttpStatusCode.fromValue(502), headers, body)
217217

218-
val mockEngine = object : HttpClientEngine {
218+
val mockEngine = object : HttpClientEngineBase("test") {
219219
override suspend fun roundTrip(request: HttpRequest): HttpCall {
220220
val now = Instant.now()
221221
return HttpCall(request, httpResp, now, now)

client-runtime/protocols/http/common/test/aws/sdk/kotlin/runtime/http/middleware/ServiceEndpointResolverTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import aws.sdk.kotlin.runtime.endpoint.EndpointResolver
1111
import aws.sdk.kotlin.runtime.execution.AuthAttributes
1212
import aws.sdk.kotlin.runtime.testing.runSuspendTest
1313
import software.aws.clientrt.http.*
14-
import software.aws.clientrt.http.engine.HttpClientEngine
14+
import software.aws.clientrt.http.engine.HttpClientEngineBase
1515
import software.aws.clientrt.http.operation.*
1616
import software.aws.clientrt.http.request.HttpRequest
1717
import software.aws.clientrt.http.response.HttpCall
@@ -28,7 +28,7 @@ class ServiceEndpointResolverTest {
2828
@Test
2929
fun `it sets the host to the expected endpoint`(): Unit = runSuspendTest {
3030
val expectedHost = "test.com"
31-
val mockEngine = object : HttpClientEngine {
31+
val mockEngine = object : HttpClientEngineBase("test") {
3232
override suspend fun roundTrip(request: HttpRequest): HttpCall {
3333
assertEquals(expectedHost, request.url.host)
3434
assertEquals(expectedHost, request.headers["Host"])
@@ -66,7 +66,7 @@ class ServiceEndpointResolverTest {
6666
@Test
6767
fun `it prepends hostPrefix when present`(): Unit = runSuspendTest {
6868
val expectedHost = "prefix.test.com"
69-
val mockEngine = object : HttpClientEngine {
69+
val mockEngine = object : HttpClientEngineBase("test") {
7070
override suspend fun roundTrip(request: HttpRequest): HttpCall {
7171
assertEquals(expectedHost, request.url.host)
7272
val resp = HttpResponse(HttpStatusCode.fromValue(200), Headers.Empty, HttpBody.Empty)
@@ -103,7 +103,7 @@ class ServiceEndpointResolverTest {
103103
fun `it overrides credential scopes`(): Unit = runSuspendTest {
104104
// if an endpoint specifies credential scopes we should override the context
105105
val expectedHost = "test.com"
106-
val mockEngine = object : HttpClientEngine {
106+
val mockEngine = object : HttpClientEngineBase("test") {
107107
override suspend fun roundTrip(request: HttpRequest): HttpCall {
108108
assertEquals(expectedHost, request.url.host)
109109
assertEquals(expectedHost, request.headers["Host"])

client-runtime/protocols/http/common/test/aws/sdk/kotlin/runtime/http/middleware/UserAgentTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import aws.sdk.kotlin.runtime.testing.runSuspendTest
1111
import software.aws.clientrt.http.Headers
1212
import software.aws.clientrt.http.HttpBody
1313
import software.aws.clientrt.http.HttpStatusCode
14-
import software.aws.clientrt.http.engine.HttpClientEngine
14+
import software.aws.clientrt.http.engine.HttpClientEngineBase
1515
import software.aws.clientrt.http.operation.*
1616
import software.aws.clientrt.http.request.HttpRequest
1717
import software.aws.clientrt.http.response.HttpCall
@@ -26,7 +26,7 @@ class UserAgentTest {
2626

2727
@Test
2828
fun `it sets ua headers`() = runSuspendTest {
29-
val mockEngine = object : HttpClientEngine {
29+
val mockEngine = object : HttpClientEngineBase("test") {
3030
override suspend fun roundTrip(request: HttpRequest): HttpCall {
3131
val resp = HttpResponse(HttpStatusCode.fromValue(200), Headers.Empty, HttpBody.Empty)
3232
val now = Instant.now()

0 commit comments

Comments
 (0)