Skip to content

feat: [CHA-2956] connection pooling: getstream-ruby#62

Open
mogita wants to merge 15 commits into
masterfrom
feat/cha-2956_connection-pooling
Open

feat: [CHA-2956] connection pooling: getstream-ruby#62
mogita wants to merge 15 commits into
masterfrom
feat/cha-2956_connection-pooling

Conversation

@mogita
Copy link
Copy Markdown
Collaborator

@mogita mogita commented May 26, 2026

Summary

Connection pooling for getstream-ruby (CHA-2956).

  • Switches the default Faraday adapter from Faraday.default_adapter (no pool) to :net_http_persistent (real per-process pool). Matches legacy stream-chat-ruby.
  • 4 new constructor kwargs: max_conns_per_host: (5), idle_timeout: (55s), connect_timeout: (10s), request_timeout: (30s).
  • http_client: escape hatch: accepts a pre-built Faraday::Connection used as-is.
  • Per-call request_timeout: override on Client#make_request.
  • One INFO log on construction listing the effective pool config.
  • Existing faraday_adapter config remains as an alternate escape hatch (pool knobs not applied when set).
  • Existing timeout: kwarg remains as a backwards-compat alias.

New runtime deps

  • faraday-net_http_persistent ~> 2.3
  • net-http-persistent ~> 4.0

Versions match stream-chat-ruby/stream-chat.gemspec.

A Gemfile-only constraint connection_pool < 3.0 was added because connection_pool 3.x requires Ruby >= 3.4 while CI runs Ruby 3.1. net-http-persistent accepts connection_pool >= 2.2.4, < 4, so the pin is safe.

Behavior change

  • Long-lived processes will now hold up to 5 idle TCP connections per upstream host until they age out at 55s.
  • Connection: keep-alive header no longer emitted on the default path (net_http_persistent keeps connections alive natively).

Test plan

  • Defaults: max_conns_per_host=5, idle_timeout=55, connect_timeout=10, request_timeout=30, adapter is NetHttpPersistent
  • Each knob individually overridable
  • timeout: kwarg still works as alias for request_timeout:
  • http_client: escape hatch: user-supplied connection used verbatim
  • faraday_adapter: escape hatch: custom adapter used; pool_size NOT passed
  • Per-call request_timeout: on make_request overrides client default
  • INFO log fires once on construction
  • bundle exec rspec spec/ (excluding integration) green: 248 examples, 0 failures
  • bundle exec rubocop clean: 36 files inspected, no offenses detected
  • bundle exec bundler-audit: only pre-existing advisories on addressable/faraday/yard (same as master). New net-http-persistent and faraday-net_http_persistent have no advisories.
  • Smoke test: bundle exec ruby -Ilib -rgetstream_ruby -e 'GetStreamRuby.manual(...)' prints expected INFO line and adapter=Faraday::Adapter::NetHttpPersistent.

Refs

  • Linear: CHA-2956
  • Legacy reference: stream-chat-ruby/lib/stream-chat/client.rb:64-72

The pool_size assertions read the handler's internal @Args ivar, whose
layout changed between Faraday 2.8 (kwargs stored in @Args) and 2.9+
(kwargs in a separate @kwargs). CI floats Faraday versions (Gemfile.lock
is gitignored for this gem), so @args.last was nil there and the two
pool_size specs failed; the faraday_adapter escape-hatch spec only passed
because its guard masked the same nil.

Intercept the public Faraday::RackBuilder#adapter call instead — the same
API the client uses — so the assertions hold regardless of how Faraday
stores args internally. Production code unchanged.
@mogita mogita changed the title [CHA-2956] connection pooling: getstream-ruby feat: [CHA-2956] connection pooling: getstream-ruby May 27, 2026
Remove Notion links and spec-section markers from changelog, client/config
comments, and spec describe labels. Behavior unchanged.
When net_http_persistent cannot be configured, configure_adapter falls
back to Faraday.default_adapter, which silently disables connection
pooling. Previously the WARNING was emitted via logger&.warn, so it was
completely silent when no logger was configured (the default for
GetStreamRuby.manual). The construction INFO line also reported the
requested faraday_adapter even when the build had silently fallen back
to a different one.

- Add Configuration#warn_pool_fallback, which emits the fallback WARNING
  via a default $stdout logger when none is configured, mirroring
  log_pool_config_to. A pooling-disable is never silent now.
- Record the effective adapter on the configuration and have
  log_pool_config_to report it, so the INFO line reflects the adapter
  actually built rather than the requested-but-failed one.
- Bump the gemspec faraday floor to ~> 2.5 to match the true floor
  imposed by faraday-net_http_persistent ~> 2.3 (needs faraday ~> 2.5).
- Correct the Gemfile comment: connection_pool 3.x requires Ruby >= 3.2,
  not >= 3.4. The < 3.0 pin stays (CI runs Ruby 3.1).
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.

1 participant