Skip to content

[CHA-2956] connection pooling: stream-sdk-java#64

Merged
mogita merged 19 commits into
mainfrom
feat/cha-2956_connection-pooling
May 28, 2026
Merged

[CHA-2956] connection pooling: stream-sdk-java#64
mogita merged 19 commits into
mainfrom
feat/cha-2956_connection-pooling

Conversation

@mogita
Copy link
Copy Markdown
Contributor

@mogita mogita commented May 26, 2026

Summary

Implements explicit HTTP connection pooling for stream-sdk-java (CHA-2956).

  • New StreamClientOptions POJO with fluent setters for the 5 canonical knobs: setMaxConnsPerHost, setIdleTimeout, setConnectTimeout, setRequestTimeout, setHttpClient.
  • New StreamSDKClient(apiKey, secret, StreamClientOptions) constructor overload.
  • Defaults: 5 / 55s / 10s / 30s.
  • INFO log on construction via java.util.logging.Logger. No new dependency.
  • Per-call RequestTimeout override: request.callTimeout(Duration.ofSeconds(5)).execute().
  • setHttpClient(OkHttpClient) is the escape hatch; bypasses all 4 knobs.
  • Existing 3-arg StreamSDKClient(apiKey, secret, OkHttpClient) escape hatch preserved.

Version bump 7.2.0 to 7.3.0.

Behavior change

Default per-call RequestTimeout moves from 10s to 30s. Aligns with the cross-SDK contract. Existing callers needing the old 10s ceiling should pass new StreamClientOptions().setRequestTimeout(Duration.ofSeconds(10)). CHANGELOG calls this out under "Changed."

Test plan

  • StreamClientOptions defaults + fluent setter chaining
  • StreamHTTPClient uses options-derived ConnectionPool + connectTimeout + callTimeout
  • StreamSDKClient(apiKey, secret, options) constructor flows options through
  • setHttpClient(OkHttpClient) escape hatch via options: 4 knobs bypassed, user pool/timeouts preserved
  • Legacy StreamSDKClient(apiKey, secret, OkHttpClient) escape hatch still works
  • Per-call request.callTimeout(Duration) pre-empts client-wide callTimeout (MockWebServer)
  • INFO log on construction with defaults (asserts each knob + user_http_client=false)
  • INFO log on construction with setHttpClient (asserts user_http_client=true)
  • ./gradlew spotlessApply clean
  • ./gradlew test --no-daemon --tests 'io.getstream.StreamHTTPClientTest' --tests 'io.getstream.StreamRequestCallTimeoutTest' 17/17 PASS
  • ./gradlew build --no-daemon -x test BUILD SUCCESSFUL

Note on full integration suite

./gradlew test --no-daemon (full suite) fails on ChatChannelIntegrationTest.testHardDeleteChannels with Task ... did not complete after 30 attempts. This is a pre-existing live-server timing flake; the same test fails identically on origin/main in the full-suite run. The 30s polling window in waitForTask is insufficient when the live backend's async hard-delete task processor is under load. Unrelated to this change. Verified by running the full suite on origin/main immediately before this PR.

Refs

Strip Notion spec links and section refs from CHANGELOG, javadoc, and
comments. Behavior unchanged; CHA-2956 references kept.
mogita added 2 commits May 27, 2026 15:26
…verrides

The env/properties constructor paths parsed STREAM_API_TIMEOUT /
io.getstream.timeout and STREAM_API_CONNECTION_MAX_AGE /
io.getstream.connection.maxAge into private fields that
defaultHttpClientBuilder() no longer reads after the CHA-2956 rewrite to
StreamClientOptions. Existing deployments relying on those env vars
silently lost their override and jumped to the 30s/55s defaults.

Fold the parsed values into the default StreamClientOptions when (and
only when) the env var / system property is explicitly present, so the
request-timeout and idle-timeout knobs honor them again. An explicitly
passed StreamClientOptions (3-arg ctor) still wins since that path never
reads env vars; an unset var leaves the options defaults intact.
maxConnsPerHost was wired only to OkHttp's ConnectionPool, which controls
the idle-pool SIZE, not a per-host concurrency ceiling. The real per-host
limit is Dispatcher.maxRequestsPerHost (OkHttp default 5). Construct a
Dispatcher and set maxRequestsPerHost to the configured maxConnsPerHost
so the knob actually caps in-flight requests per host; keep the existing
ConnectionPool sizing too. The OkHttp default (5) equals our default, so
default behavior is unchanged.

Also apply idleTimeout with millisecond precision (toMillis +
MILLISECONDS) for parity with the other Duration knobs instead of
truncating to whole seconds, and correct the user-http-client INFO log to
say "4 knobs" (setHttpClient is the escape hatch itself, not a tunable).
@mogita mogita merged commit 7e1238e into main May 28, 2026
1 of 2 checks passed
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.

2 participants