Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/getstream_ruby/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,14 @@ def assign_timeouts_and_pool(options, use_env:)
if use_env
env_request_timeout = ENV.fetch('STREAM_REQUEST_TIMEOUT', nil) || ENV.fetch('STREAM_TIMEOUT', nil)
@request_timeout = (request_timeout || timeout || env_request_timeout || 30).to_i
@max_conns_per_host = (max_conns_per_host || ENV.fetch('STREAM_MAX_CONNS_PER_HOST', nil) || 5).to_i
@max_conns_per_host = (max_conns_per_host || ENV.fetch('STREAM_MAX_CONNS_PER_HOST', nil) || 100).to_i

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

net-http-persistent 4.0.8 checks idle_timeout only when a connection is checked out, and its pool hands back the most recently used connection first. After a burst, only the connections needed for steady traffic get reused, and the rest stay open past the LB idle close (CLOSE_WAIT) until the next burst. With 50 threads settling at about 5 concurrent requests, that is 45 dead sockets per process per client, where the old cap bounded it at 5. The PR body says an idle app opens no extra sockets, which holds only before the first burst.

@mogita mogita Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept 100. The extra sockets are bounded by the peak number of threads in a request, and past 5 those threads used to wait at most 0.5s on the pool and then raise ConnectionPool::TimeoutError. Corrected the PR body.

# 25s sits under GCP SSL-proxy idle (~30s) and AWS ALB idle (60s) so
# net_http_persistent drops the conn before the LB does (CHA-4943).
@idle_timeout = (idle_timeout || ENV.fetch('STREAM_IDLE_TIMEOUT', nil) || 25).to_i
@connect_timeout = (connect_timeout || ENV.fetch('STREAM_CONNECT_TIMEOUT', nil) || 10).to_i
else
@request_timeout = (request_timeout || timeout || 30).to_i
@max_conns_per_host = (max_conns_per_host || 5).to_i
@max_conns_per_host = (max_conns_per_host || 100).to_i
@idle_timeout = (idle_timeout || 25).to_i
@connect_timeout = (connect_timeout || 10).to_i
end
Expand Down
6 changes: 3 additions & 3 deletions spec/connection_pooling_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ def capture_adapter_call

end

it 'passes pool_size=5 to the net_http_persistent adapter' do
it 'passes pool_size=100 to the net_http_persistent adapter' do

captured = capture_adapter_call { GetStreamRuby.manual(api_key: 'k', api_secret: 's') }
expect(captured[:args].first).to eq(:net_http_persistent)
expect(captured[:kwargs]).to include(pool_size: 5)
expect(captured[:kwargs]).to include(pool_size: 100)

end

Expand Down Expand Up @@ -229,7 +229,7 @@ def capture_adapter_call
expect(info_lines.size).to eq(1)
line = info_lines.first
expect(line).to include('client.initialized')
expect(line).to include('stream.client.max_conns_per_host=5')
expect(line).to include('stream.client.max_conns_per_host=100')
expect(line).to include('stream.client.idle_timeout_seconds=25')
expect(line).to include('stream.client.connect_timeout_seconds=10')
expect(line).to include('stream.client.request_timeout_seconds=30')
Expand Down
2 changes: 1 addition & 1 deletion spec/getstream_ruby_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
expect(client.configuration.faraday_adapter).to be_nil
expect(client.configuration.faraday_adapter_options).to eq({})
expect(client.configuration.connection_keep_alive).to eq(true)
expect(client.configuration.max_conns_per_host).to eq(5)
expect(client.configuration.max_conns_per_host).to eq(100)
expect(client.configuration.idle_timeout).to eq(25)
expect(client.configuration.connect_timeout).to eq(10)
expect(client.configuration.request_timeout).to eq(30)
Expand Down
Loading