Skip to content

Commit 002c10d

Browse files
fix(client): don't close client on withOptions usage when original is gc'd
1 parent cbc078a commit 002c10d

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

orb-java-core/src/main/kotlin/com/withorb/api/core/ClientOptions.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ private constructor(
9898
webhookSecret = clientOptions.webhookSecret
9999
}
100100

101-
fun httpClient(httpClient: HttpClient) = apply { this.httpClient = httpClient }
101+
fun httpClient(httpClient: HttpClient) = apply {
102+
this.httpClient = PhantomReachableClosingHttpClient(httpClient)
103+
}
102104

103105
fun checkJacksonVersionCompatibility(checkJacksonVersionCompatibility: Boolean) = apply {
104106
this.checkJacksonVersionCompatibility = checkJacksonVersionCompatibility
@@ -255,14 +257,12 @@ private constructor(
255257

256258
return ClientOptions(
257259
httpClient,
258-
PhantomReachableClosingHttpClient(
259-
RetryingHttpClient.builder()
260-
.httpClient(httpClient)
261-
.clock(clock)
262-
.maxRetries(maxRetries)
263-
.idempotencyHeader("Idempotency-Key")
264-
.build()
265-
),
260+
RetryingHttpClient.builder()
261+
.httpClient(httpClient)
262+
.clock(clock)
263+
.maxRetries(maxRetries)
264+
.idempotencyHeader("Idempotency-Key")
265+
.build(),
266266
checkJacksonVersionCompatibility,
267267
jsonMapper,
268268
streamHandlerExecutor
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// File generated from our OpenAPI spec by Stainless.
2+
3+
package com.withorb.api.core
4+
5+
import com.withorb.api.core.http.HttpClient
6+
import org.assertj.core.api.Assertions.assertThat
7+
import org.junit.jupiter.api.Test
8+
import org.junit.jupiter.api.extension.ExtendWith
9+
import org.mockito.junit.jupiter.MockitoExtension
10+
import org.mockito.kotlin.mock
11+
import org.mockito.kotlin.never
12+
import org.mockito.kotlin.verify
13+
14+
@ExtendWith(MockitoExtension::class)
15+
internal class ClientOptionsTest {
16+
17+
@Test
18+
fun toBuilder_whenOriginalClientOptionsGarbageCollected_doesNotCloseOriginalClient() {
19+
val httpClient = mock<HttpClient>()
20+
var clientOptions =
21+
ClientOptions.builder().httpClient(httpClient).apiKey("My API Key").build()
22+
verify(httpClient, never()).close()
23+
24+
// Overwrite the `clientOptions` variable so that the original `ClientOptions` is GC'd.
25+
clientOptions = clientOptions.toBuilder().build()
26+
System.gc()
27+
Thread.sleep(100)
28+
29+
verify(httpClient, never()).close()
30+
// This exists so that `clientOptions` is still reachable.
31+
assertThat(clientOptions).isEqualTo(clientOptions)
32+
}
33+
}

0 commit comments

Comments
 (0)