Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

fix: closing a withOptions client closes shared resources

Abierto
#850 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@abhinavkr26104 ya está trabajando en esto.

Desde el 10/8/2026.

  • #851 de @abhinavkr26104 — abierto

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
java, kotlin
Área
api

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-228 copies originalHttpClient, streamHandlerExecutor, and sleeper into a new builder.
  • openai-java-core/src/main/kotlin/com/openai/core/ClientOptions.kt:257-259 wraps 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-777 closes the HTTP client, executor, and sleeper unconditionally.
  • openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt:146-147 and OpenAIClientAsyncImpl.kt:166-167 implement withOptions() by building a new client from clientOptions.toBuilder().
  • openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt:61-66 and OpenAIClientAsync.kt:61-66 document 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

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de openai/openai-java

Todos los issues de openai/openai-java

Issues similares

Más issues de Kotlin

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.