fix: closing a withOptions client closes shared resources
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
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-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.
- Lingua principale
- Kotlin
- Stelle
- 1.5k
- Fork
- 266
- Merge medio
- 9h 50m
- PR unite (30g)
- 146
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di openai/openai-java
-
HttpRequest.url() logs spaces in path segments as literal plus signsForse già presa @sylvesterkaczmarek l’ha presa 53 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
openai/openai-java#886 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Make diarized transcription duration and task optionalForse già presa @wskr00 l’ha presa 83 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
openai/openai-java#802 · 2 commenti · 3 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
AsyncStreamResponse can hang when the subscriber executor rejects workForse già presa @sylvesterkaczmarek l’ha presa 36 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 74/100
openai/openai-java#973 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
openai/openai-java#956 ·
I maintainer di solito rispondono entro 1 giorno
-
Async internal plumbing bypasses both `dispatcherExecutorService` and `streamHandlerExecutor`, forcing a hop through `ForkJoinPool.commonPool()`Forse già presa @sylvesterkaczmarek l’ha presa 30 giorni fa. Aperta
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
openai/openai-java#952 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di openai/openai-java
Issue simili
-
enhancement
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 72/100
afarber/OpenMapView#22 ·
-
Feature:Resolution
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
intellij-elixir/intellij-elixir#4396 ·
I maintainer di solito rispondono entro 1 giorno
-
ExprQuerySet.getChildren() omits WITH clauseForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
partiql/partiql-lang-kotlin#1972 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
navikt/soknadsarkiverer#293 ·
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
FoedusProgramme/Gramophone#1048 ·