Skip to content

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

Merged
copybara-service[bot] merged 1 commit into
mainfrom
test_945640677
Jul 14, 2026
Merged

feat: share a single OkHttpClient with injectable daemon threads across the ADK#1349
copybara-service[bot] merged 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 6 times, most recently from 86e867c to 0df8883 Compare July 14, 2026 08:39
…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: 947525602
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