From a7a552fb0afb739f99f54b56b36e516bf5408f1e Mon Sep 17 00:00:00 2001 From: Jonas Alves Date: Mon, 26 Jan 2026 09:51:18 +0000 Subject: [PATCH 1/4] feat: expose pool_size and pool_idle_timeout as configurable options Add configurable connection pool settings for the HTTP client: - pool_size (default: 20) - number of connections in the pool - pool_idle_timeout (default: 5) - seconds before idle connections close This allows customers to tune connection pooling behavior based on their specific workload requirements. --- CHANGELOG.md | 3 + Gemfile.lock | 68 ++++++++++++----------- README.md | 4 ++ lib/default_http_client.rb | 4 +- lib/default_http_client_config.rb | 6 +- spec/default_http_client_config_spec.rb | 14 +++++ spec/default_http_client_spec.rb | 73 ++++++++++++++++++++++++- 7 files changed, 135 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e7d505..118e3cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## [Unreleased] +### Added +- Configurable connection pool settings: `pool_size` and `pool_idle_timeout` + ## [0.1.0] - 2022-08-03 - Initial release diff --git a/Gemfile.lock b/Gemfile.lock index 366ed8a..ff0a361 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,12 +11,13 @@ PATH GEM remote: https://rubygems.org/ specs: - ast (2.4.2) + ast (2.4.3) base64 (0.3.0) byebug (11.1.3) connection_pool (2.5.5) - diff-lcs (1.5.0) - faraday (2.7.4) + diff-lcs (1.6.2) + faraday (2.8.1) + base64 faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) @@ -25,54 +26,55 @@ GEM net-http-persistent (>= 4.0.4, < 5) faraday-retry (2.4.0) faraday (~> 2.0) - io-console (0.5.6) - irb (1.2.6) - reline (>= 0.1.5) - json (2.6.2) + io-console (0.8.2) + irb (1.6.3) + reline (>= 0.3.0) + json (2.7.6) murmurhash3 (0.1.7) net-http-persistent (4.0.8) connection_pool (>= 2.2.4, < 4) - parallel (1.22.1) - parser (3.1.2.0) + parallel (1.24.0) + parser (3.3.10.1) ast (~> 2.4.1) + racc + racc (1.8.1) rainbow (3.1.1) - rake (13.0.6) - regexp_parser (2.5.0) - reline (0.1.5) + rake (13.3.1) + regexp_parser (2.11.3) + reline (0.6.3) io-console (~> 0.5) rexml (3.4.4) - rspec (3.11.0) - rspec-core (~> 3.11.0) - rspec-expectations (~> 3.11.0) - rspec-mocks (~> 3.11.0) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.0) + rspec (3.13.2) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-mocks (3.11.1) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.7) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-support (3.11.0) - rubocop (1.33.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.6) + rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) - parser (>= 3.1.0.0) + parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.19.1, < 2.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.19.1) - parser (>= 3.1.1.0) - ruby-progressbar (1.11.0) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.30.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) - unicode-display_width (2.2.0) + unicode-display_width (2.6.0) PLATFORMS - ruby - x86_64-darwin-20 + universal-darwin-24 DEPENDENCIES absmartly-sdk! diff --git a/README.md b/README.md index 56745e2..d83f029 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ Absmartly.configure_client do |config| config.connection_request_timeout = 3.0 config.retry_interval = 0.5 config.max_retries = 5 + config.pool_size = 20 + config.pool_idle_timeout = 5 end ``` @@ -48,6 +50,8 @@ end | connection_request_timeout | `number` | ❌ | `3.0` | The request timeout in seconds. | | retry_interval | `number` | ❌ | `0.5` | The initial retry interval in seconds (uses exponential backoff). | | max_retries | `number` | ❌ | `5` | The maximum number of retries before giving up. | +| pool_size | `number` | ❌ | `20` | The number of connections in the HTTP connection pool. | +| pool_idle_timeout | `number` | ❌ | `5` | The time in seconds before idle connections are closed. | | event_logger | `ContextEventLogger` | ❌ | See "Using a Custom Event Logger" below | A `ContextEventLogger` instance implementing `handle_event(event, data)` to receive SDK events. | ### Using a Custom Event Logger diff --git a/lib/default_http_client.rb b/lib/default_http_client.rb index 7b8aef3..8381cdb 100644 --- a/lib/default_http_client.rb +++ b/lib/default_http_client.rb @@ -23,8 +23,8 @@ def initialize(config) backoff_factor: 2 f.options.timeout = config.connect_timeout f.options.open_timeout = config.connection_request_timeout - f.adapter :net_http_persistent, pool_size: 20 do |http| - http.idle_timeout = 5 + f.adapter :net_http_persistent, pool_size: config.pool_size do |http| + http.idle_timeout = config.pool_idle_timeout end end end diff --git a/lib/default_http_client_config.rb b/lib/default_http_client_config.rb index 016ed3b..1cd212f 100644 --- a/lib/default_http_client_config.rb +++ b/lib/default_http_client_config.rb @@ -4,7 +4,9 @@ class DefaultHttpClientConfig attr_accessor :connect_timeout, :connection_request_timeout, :retry_interval, - :max_retries + :max_retries, + :pool_size, + :pool_idle_timeout def self.create DefaultHttpClientConfig.new @@ -15,5 +17,7 @@ def initialize @connection_request_timeout = 3.0 @retry_interval = 0.5 @max_retries = 5 + @pool_size = 20 + @pool_idle_timeout = 5 end end diff --git a/spec/default_http_client_config_spec.rb b/spec/default_http_client_config_spec.rb index 17d8e3f..14465a0 100644 --- a/spec/default_http_client_config_spec.rb +++ b/spec/default_http_client_config_spec.rb @@ -21,4 +21,18 @@ config.retry_interval = 123 expect(config.retry_interval).to eq(123) end + + it ".pool_size" do + config = described_class.new + expect(config.pool_size).to eq(20) + config.pool_size = 50 + expect(config.pool_size).to eq(50) + end + + it ".pool_idle_timeout" do + config = described_class.new + expect(config.pool_idle_timeout).to eq(5) + config.pool_idle_timeout = 10 + expect(config.pool_idle_timeout).to eq(10) + end end diff --git a/spec/default_http_client_spec.rb b/spec/default_http_client_spec.rb index 099231e..8260aa3 100644 --- a/spec/default_http_client_spec.rb +++ b/spec/default_http_client_spec.rb @@ -1,7 +1,78 @@ # frozen_string_literal: true require "default_http_client" -require "context" +require "default_http_client_config" RSpec.describe DefaultHttpClient do + describe "#initialize" do + it "configures Faraday with custom pool_size" do + config = DefaultHttpClientConfig.create + config.pool_size = 42 + + expect_any_instance_of(Faraday::Connection).to receive(:adapter) + .with(:net_http_persistent, pool_size: 42) + .and_call_original + + described_class.create(config) + end + + it "configures Faraday with custom pool_idle_timeout" do + config = DefaultHttpClientConfig.create + config.pool_idle_timeout = 15 + + block_called = false + idle_timeout_value = nil + + allow_any_instance_of(Faraday::Connection).to receive(:adapter) + .with(:net_http_persistent, pool_size: config.pool_size) do |&block| + http = double("http") + allow(http).to receive(:idle_timeout=) { |val| idle_timeout_value = val } + block.call(http) if block + block_called = true + end + + described_class.create(config) + + expect(block_called).to be true + expect(idle_timeout_value).to eq(15) + end + + it "uses default pool_size of 20" do + config = DefaultHttpClientConfig.create + + expect_any_instance_of(Faraday::Connection).to receive(:adapter) + .with(:net_http_persistent, pool_size: 20) + .and_call_original + + described_class.create(config) + end + + it "uses default pool_idle_timeout of 5" do + config = DefaultHttpClientConfig.create + + block_called = false + idle_timeout_value = nil + + allow_any_instance_of(Faraday::Connection).to receive(:adapter) + .with(:net_http_persistent, pool_size: 20) do |&block| + http = double("http") + allow(http).to receive(:idle_timeout=) { |val| idle_timeout_value = val } + block.call(http) if block + block_called = true + end + + described_class.create(config) + + expect(block_called).to be true + expect(idle_timeout_value).to eq(5) + end + + it "uses the net_http_persistent adapter" do + config = DefaultHttpClientConfig.create + client = described_class.create(config) + adapter = client.session.builder.adapter + + expect(adapter.klass).to eq(Faraday::Adapter::NetHttpPersistent) + end + end end From a063e3751ce7cf6a461cb202a46cf0d50ef22f75 Mon Sep 17 00:00:00 2001 From: Jonas Alves Date: Mon, 26 Jan 2026 09:57:40 +0000 Subject: [PATCH 2/4] fix: add x86_64-linux platform to Gemfile.lock for CI --- Gemfile.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile.lock b/Gemfile.lock index ff0a361..a83e16f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,6 +75,7 @@ GEM PLATFORMS universal-darwin-24 + x86_64-linux DEPENDENCIES absmartly-sdk! From d28fdbff457c96da3ea78bb8ea7c29f9b4c9623d Mon Sep 17 00:00:00 2001 From: Jonas Alves Date: Mon, 26 Jan 2026 09:59:07 +0000 Subject: [PATCH 3/4] fix: add x86_64-linux and ruby platforms to Gemfile.lock for CI --- Gemfile.lock | 1 + spec/spec_helper.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index a83e16f..025cbc1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,6 +74,7 @@ GEM unicode-display_width (2.6.0) PLATFORMS + ruby universal-darwin-24 x86_64-linux diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4b08390..a4c06b3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "ostruct" require "absmartly" require "helpers" From a183ced0b5870c9e701264b72b9edfe53032f8fd Mon Sep 17 00:00:00 2001 From: Jonas Alves Date: Mon, 26 Jan 2026 10:09:55 +0000 Subject: [PATCH 4/4] chore: bump version to 1.3.0 --- Gemfile.lock | 70 +++++++++++++++++++--------------------- lib/absmartly/version.rb | 2 +- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 025cbc1..e1108ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - absmartly-sdk (1.3.0.pre.1) + absmartly-sdk (1.3.0) base64 (~> 0.2) faraday (~> 2.0) faraday-net_http_persistent (~> 2.0) @@ -11,13 +11,12 @@ PATH GEM remote: https://rubygems.org/ specs: - ast (2.4.3) + ast (2.4.2) base64 (0.3.0) byebug (11.1.3) connection_pool (2.5.5) - diff-lcs (1.6.2) - faraday (2.8.1) - base64 + diff-lcs (1.5.0) + faraday (2.7.4) faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) @@ -26,57 +25,54 @@ GEM net-http-persistent (>= 4.0.4, < 5) faraday-retry (2.4.0) faraday (~> 2.0) - io-console (0.8.2) - irb (1.6.3) - reline (>= 0.3.0) - json (2.7.6) + io-console (0.5.6) + irb (1.2.6) + reline (>= 0.1.5) + json (2.6.2) murmurhash3 (0.1.7) net-http-persistent (4.0.8) connection_pool (>= 2.2.4, < 4) - parallel (1.24.0) - parser (3.3.10.1) + parallel (1.22.1) + parser (3.1.2.0) ast (~> 2.4.1) - racc - racc (1.8.1) rainbow (3.1.1) - rake (13.3.1) - regexp_parser (2.11.3) - reline (0.6.3) + rake (13.0.6) + regexp_parser (2.5.0) + reline (0.1.5) io-console (~> 0.5) rexml (3.4.4) - rspec (3.13.2) - rspec-core (~> 3.13.0) - rspec-expectations (~> 3.13.0) - rspec-mocks (~> 3.13.0) - rspec-core (3.13.6) - rspec-support (~> 3.13.0) - rspec-expectations (3.13.5) + rspec (3.11.0) + rspec-core (~> 3.11.0) + rspec-expectations (~> 3.11.0) + rspec-mocks (~> 3.11.0) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.13.0) - rspec-mocks (3.13.7) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.13.0) - rspec-support (3.13.6) - rubocop (1.50.2) + rspec-support (~> 3.11.0) + rspec-support (3.11.0) + rubocop (1.33.0) json (~> 2.3) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.1.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) + rubocop-ast (>= 1.19.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - ruby-progressbar (1.13.0) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.19.1) + parser (>= 3.1.1.0) + ruby-progressbar (1.11.0) ruby2_keywords (0.0.5) - unicode-display_width (2.6.0) + unicode-display_width (2.2.0) PLATFORMS ruby - universal-darwin-24 - x86_64-linux + x86_64-darwin-20 DEPENDENCIES absmartly-sdk! diff --git a/lib/absmartly/version.rb b/lib/absmartly/version.rb index 3a57db0..bdfd7b2 100644 --- a/lib/absmartly/version.rb +++ b/lib/absmartly/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Absmartly - VERSION = "1.3.0.pre.1" + VERSION = "1.3.0" end