Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

fix: closing a withOptions client closes shared resources

Aperta
#850 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@abhinavkr26104 ci sta già lavorando.

Dal 10/8/2026.

  • #851 di @abhinavkr26104 — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
java, kotlin
Ambito
api

Direzione di ricerca

Inizia da ClientOptions.kt, in particolare dalla copia del builder alle righe 222-228, dalla configurazione dell’ownership alle righe 257-259 e dalla logica di chiusura alle righe 773-777; poi traccia withOptions() in OpenAIClientImpl.kt e OpenAIClientAsyncImpl.kt. Verifica che i client derivati e quelli originali rimangano utilizzabili in entrambi gli ordini di chiusura per i client sync e async, incluso il ciclo di vita di transport, executor e sleeper.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
Kotlin
Stelle
1.5k
Fork
266
Merge medio
9h 50m
PR unite (30g)
146

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di openai/openai-java

Tutte le issue di openai/openai-java

Issue simili

Altre issue su Kotlin

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.