fix: closing a withOptions client closes shared resources
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
Hướng nghiên cứu
Bắt đầu với ClientOptions.kt, đặc biệt là việc sao chép của builder ở các dòng 222-228, thiết lập ownership ở 257-259 và logic đóng ở 773-777; sau đó theo dõi withOptions() trong OpenAIClientImpl.kt và OpenAIClientAsyncImpl.kt. Xác minh rằng các client dẫn xuất và client ban đầu vẫn có thể sử dụng được theo cả hai thứ tự đóng đối với các client sync và async, bao gồm cả vòng đời của transport, executor và sleeper.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- Kotlin
- Star
- 1.5k
- Fork
- 268
- Merge trung bình
- 13 giờ 30 phút
- Pull request đã merge (30 ngày)
- 160
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của openai/openai-java
-
HttpRequest.url() logs spaces in path segments as literal plus signsCó thể đã có người làm @sylvesterkaczmarek đã nhận 58 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
openai/openai-java#886 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Make diarized transcription duration and task optionalCó thể đã có người làm @wskr00 đã nhận 89 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
openai/openai-java#802 · 2 bình luận · 3 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 30/100
openai/openai-java#1175 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 Nửa ngày Mức phù hợp với người mới 42/100
openai/openai-java#1160 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
openai/openai-java#956 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của openai/openai-java
Issue tương tự
-
jules
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 82/100
open-learning-exchange/myplanet#18199 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 4 ngày
-
getCredentials fails on an unrecognized fingerprint while the biometric prompt is still openĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
auth0/Auth0.Android#1095 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Scheme-less stream URLs throw NullPointerException instead of URISyntaxExceptionCó thể đã có người làm @blihio đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
pedroSG94/RootEncoder#2218 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
二维码代签解析失败Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
aquamarine5/ChaoxingSignFaker#235 · 2 bình luận ·