Skip to content

feat: share a single OkHttpClient with injectable daemon threads across the ADK#1349

Open
copybara-service[bot] wants to merge 1 commit into
mainfrom
test_945640677
Open

feat: share a single OkHttpClient with injectable daemon threads across the ADK#1349
copybara-service[bot] wants to merge 1 commit into
mainfrom
test_945640677

Conversation

@copybara-service

@copybara-service copybara-service Bot commented Jul 13, 2026

Copy link
Copy Markdown

feat: share a single OkHttpClient with injectable daemon threads across the ADK

Building a separate OkHttpClient per model or session leaks connection pools and
threads. This routes Gemini, ChatCompletionsHttpClient, and the sessions
ApiClient through HttpClientFactory, which caches one shared client per name so
the dispatcher and connection pool are reused.

Threading is injectable at construction rather than hard-coded:

  • getOrCreateSharedHttpClient(name): the shared client, OkHttp's default
    threading.
  • createHttpClient(executor): a new client whose dispatcher runs on the given
    executor; not cached, so the caller owns the executor and the returned client.
  • daemonExecutor(name): an unbounded daemon-thread pool so a standalone or CLI
    JVM can exit once work is done.
  • Gemini.builder().httpExecutorService(...) and a new
    ChatCompletionsHttpClient(HttpOptions, ExecutorService) constructor accept the
    executor at construction. The sessions client issues synchronous requests, which
    do not use the dispatcher executor, so it shares the pool only.

Gemini forks the shared client with zeroed connect/read/write timeouts to keep
the prior infinite-timeout behavior.

Adds HttpClientFactoryTest covering caching by name, executor injection, and
daemon threads.

@copybara-service copybara-service Bot force-pushed the test_945640677 branch 2 times, most recently from 5f02d1a to 67a4070 Compare July 13, 2026 12:55
…ss the ADK

Building a separate `OkHttpClient` per model or session leaks connection pools and
threads. This routes `Gemini`, `ChatCompletionsHttpClient`, and the sessions
`ApiClient` through `HttpClientFactory`, which caches one shared client per name so
the dispatcher and connection pool are reused.

Threading is injectable at construction rather than hard-coded:

- `getOrCreateSharedHttpClient(name)`: the shared client, OkHttp's default
  threading.
- `createHttpClient(executor)`: a new client whose dispatcher runs on the given
  executor; not cached, so the caller owns the executor and the returned client.
- `daemonExecutor(name)`: an unbounded daemon-thread pool so a standalone or CLI
  JVM can exit once work is done.
- `Gemini.builder().httpExecutorService(...)` and a new
  `ChatCompletionsHttpClient(HttpOptions, ExecutorService)` constructor accept the
  executor at construction. The sessions client issues synchronous requests, which
  do not use the dispatcher executor, so it shares the pool only.

`Gemini` forks the shared client with zeroed connect/read/write timeouts to keep
the prior infinite-timeout behavior.

Adds `HttpClientFactoryTest` covering caching by name, executor injection, and
daemon threads.

PiperOrigin-RevId: 945640677
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants