fix: closing a withOptions client closes shared resources
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
Línea de trabajo
Comienza con ClientOptions.kt, especialmente con la copia del builder en las líneas 222-228, la configuración de ownership en 257-259 y la lógica de cierre en 773-777; después, sigue withOptions() en OpenAIClientImpl.kt y OpenAIClientAsyncImpl.kt. Verifica que los clientes derivados y originales sigan siendo utilizables en ambos órdenes de cierre para clientes sync y async, incluido el ciclo de vida de transport, executor y sleeper.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Description
withOptions() returns a derived client/view, but the derived client shares several resources with the original client and then treats them as independently owned. Closing the derived client can therefore shut down the original client's HTTP transport, streaming executor, and sleeper.
The public API documents withOptions() as returning a view and says that the original service is not modified, so callers reasonably expect the original client to remain usable after closing a short-lived derived client.
Reproduction
A minimal reproduction can use a custom HttpClient whose close() records a flag:
val transport = RecordingHttpClient()
val original =
ClientOptions.builder()
.httpClient(transport)
.apiKey(test)
.build()
val derived = original.toBuilder().build()
derived.close()
// Expected: transport is still open and original can execute requests.
// Actual: transport.close() has been called, and the original now uses a closed transport.
check(!transport.closed)
The same lifecycle is exposed through the public clients:
OpenAIClient original = OpenAIOkHttpClient.builder().apiKey(test).build();
OpenAIClient derived = original.withOptions(options -> options.baseUrl(https://example.test));
derived.close();
// The original should still be usable, but its shared transport/executor has been closed.
original.models().list();
Code reference
openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:222-228copiesoriginalHttpClient,streamHandlerExecutor, andsleeperinto a new builder.openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:257-259wraps the supplied HTTP client, and the class documentation says the options object owns and closes it.openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:773-777closes the HTTP client, executor, and sleeper unconditionally.openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt:146-147andOpenAIClientAsyncImpl.kt:166-167implementwithOptions()by building a new client fromclientOptions.toBuilder().openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt:61-66andOpenAIClientAsync.kt:61-66document the result as a view whose original service is not modified.
Expected behavior
Closing a derived client should not invalidate the original client or any resources still owned by it. Resource ownership should either be shared through a lifecycle holder/reference count, or derived views should be non-owning and leave shared resources to the original owner.
This should be covered for sync and async clients, including closing the derived client before the original and closing the original before the derived.
Why it matters
This can cause intermittent failures in applications that create per-request clients with withOptions() and close them promptly: later requests through the long-lived original client may fail because the HTTP transport is closed, the streaming executor rejects tasks, or the sleeper is no longer usable. It also makes the documented view semantics unsafe.
- Lenguaje dominante
- Kotlin
- Estrellas
- 1.5k
- Forks
- 268
- Merge medio
- 11 h 31 min
- PR fusionados (30 d)
- 150
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de openai/openai-java
-
HttpRequest.url() logs spaces in path segments as literal plus signsPosiblemente ocupada @sylvesterkaczmarek la tomó hace 56 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
openai/openai-java#886 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Make diarized transcription duration and task optionalPosiblemente ocupada @wskr00 la tomó hace 87 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
openai/openai-java#802 · 2 comentarios · 3 reacciones ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 30/100
openai/openai-java#1175 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 Medio día Aptitud para principiantes 42/100
openai/openai-java#1160 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
openai/openai-java#956 ·
Los mantenedores suelen responder en 1 día
Todos los issues de openai/openai-java
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
callstack/react-native-brownfield#492 · 1 comentario ·
Los mantenedores suelen responder en 4 días
-
fix: retain the best partial noise-correction solutionPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
world-federation-of-advertisers/cross-media-measurement#4653 ·
Los mantenedores suelen responder en 1 día
-
enhancement help wanted
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
kabirvashisht4-glitch/Vet#22 ·
-
documentation good first issue
Dificultad 1/5 1-3 horas Aptitud para principiantes 85/100
djazairdev/wilayas#23 ·
Los mantenedores suelen responder en 1 día