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..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) 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/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 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 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"