diff --git a/Gemfile.lock b/Gemfile.lock index b844b11..20993ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - absmartly-sdk (1.2.2) + absmartly-sdk (1.2.3) base64 (~> 0.2) faraday (~> 2.0) faraday-retry (~> 2.0) diff --git a/README.md b/README.md index ad73463..aaae440 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ Absmartly.configure_client do |config| config.api_key = "YOUR-API-KEY" config.application = "website" config.environment = "development" + config.connect_timeout = 3.0 + config.connection_request_timeout = 3.0 + config.retry_interval = 0.5 + config.max_retries = 5 end ``` @@ -37,11 +41,13 @@ end | Config | Type | Required? | Default | Description | | :---------- | :----------------------------------- | :-------: | :-------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | endpoint | `string` | ✅ | `undefined` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` | -| apiKey | `string` | ✅ | `undefined` | Your API key which can be found on the Web Console. | +| api_key | `string` | ✅ | `undefined` | Your API key which can be found on the Web Console. | | environment | `"production"` or `"development"` | ✅ | `undefined` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. | | application | `string` | ✅ | `undefined` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. | -| retries | `number` | ❌ | `5` | The number of retries before the SDK stops trying to connect. | -| timeout | `number` | ❌ | `3000` | An amount of time, in milliseconds, before the SDK will stop trying to connect. | +| connect_timeout | `number` | ❌ | `3.0` | The socket connection timeout in seconds. | +| 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. | | eventLogger | `(context, eventName, data) => void` | ❌ | See "Using a Custom Event Logger" below | A callback function which runs after SDK events. | ### Using a Custom Event Logger diff --git a/lib/absmartly.rb b/lib/absmartly.rb index 468ce29..3c26327 100644 --- a/lib/absmartly.rb +++ b/lib/absmartly.rb @@ -12,7 +12,8 @@ class Error < StandardError end class << self - attr_accessor :endpoint, :api_key, :application, :environment + attr_accessor :endpoint, :api_key, :application, :environment, + :connect_timeout, :connection_request_timeout, :retry_interval, :max_retries def configure_client yield self @@ -45,6 +46,10 @@ def client_config @client_config.api_key = @api_key @client_config.application = @application @client_config.environment = @environment + @client_config.connect_timeout = @connect_timeout + @client_config.connection_request_timeout = @connection_request_timeout + @client_config.retry_interval = @retry_interval + @client_config.max_retries = @max_retries @client_config end diff --git a/lib/absmartly/version.rb b/lib/absmartly/version.rb index 56b13dc..adf56d9 100644 --- a/lib/absmartly/version.rb +++ b/lib/absmartly/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Absmartly - VERSION = "1.2.2" + VERSION = "1.2.3" end diff --git a/lib/client.rb b/lib/client.rb index 177ad11..7c13c60 100644 --- a/lib/client.rb +++ b/lib/client.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require_relative "default_http_client" -require_relative "default_http_client_config" require_relative "default_context_data_deserializer" require_relative "default_context_event_serializer" @@ -10,7 +9,7 @@ class Client attr_reader :data_future, :promise, :exception def self.create(config, http_client = nil) - Client.new(config, http_client || DefaultHttpClient.create(DefaultHttpClientConfig.create)) + Client.new(config, http_client || DefaultHttpClient.create(config.http_client_config)) end def initialize(config, http_client = nil) diff --git a/lib/client_config.rb b/lib/client_config.rb index 7434da5..104a8a3 100644 --- a/lib/client_config.rb +++ b/lib/client_config.rb @@ -1,8 +1,11 @@ # frozen_string_literal: true +require_relative "default_http_client_config" + class ClientConfig attr_accessor :endpoint, :api_key, :environment, :application, :deserializer, - :serializer, :executor + :serializer, :executor, :connect_timeout, :connection_request_timeout, + :retry_interval, :max_retries def self.create ClientConfig.new @@ -40,4 +43,13 @@ def context_event_serializer def context_event_serializer=(serializer) @serializer = serializer end + + def http_client_config + http_config = DefaultHttpClientConfig.create + http_config.connect_timeout = @connect_timeout unless @connect_timeout.nil? + http_config.connection_request_timeout = @connection_request_timeout unless @connection_request_timeout.nil? + http_config.retry_interval = @retry_interval unless @retry_interval.nil? + http_config.max_retries = @max_retries unless @max_retries.nil? + http_config + end end diff --git a/spec/absmartly_spec.rb b/spec/absmartly_spec.rb index 11c8650..6b9a55a 100644 --- a/spec/absmartly_spec.rb +++ b/spec/absmartly_spec.rb @@ -4,4 +4,39 @@ it "has a version number" do expect(Absmartly::VERSION).not_to be nil end + + describe ".configure_client" do + after do + Absmartly.endpoint = nil + Absmartly.api_key = nil + Absmartly.application = nil + Absmartly.environment = nil + Absmartly.connect_timeout = nil + Absmartly.connection_request_timeout = nil + Absmartly.retry_interval = nil + Absmartly.max_retries = nil + end + + it "sets HTTP config options" do + Absmartly.configure_client do |config| + config.endpoint = "https://test.absmartly.io/v1" + config.api_key = "test-api-key" + config.application = "website" + config.environment = "development" + config.connect_timeout = 5.0 + config.connection_request_timeout = 10.0 + config.retry_interval = 1.0 + config.max_retries = 3 + end + + expect(Absmartly.endpoint).to eq("https://test.absmartly.io/v1") + expect(Absmartly.api_key).to eq("test-api-key") + expect(Absmartly.application).to eq("website") + expect(Absmartly.environment).to eq("development") + expect(Absmartly.connect_timeout).to eq(5.0) + expect(Absmartly.connection_request_timeout).to eq(10.0) + expect(Absmartly.retry_interval).to eq(1.0) + expect(Absmartly.max_retries).to eq(3) + end + end end diff --git a/spec/client_config_spec.rb b/spec/client_config_spec.rb index b61b995..8c8ed2d 100644 --- a/spec/client_config_spec.rb +++ b/spec/client_config_spec.rb @@ -3,6 +3,7 @@ require "client_config" require "context_data_deserializer" require "context_event_serializer" +require "default_http_client_config" RSpec.describe ClientConfig do it ".endpoint" do @@ -80,4 +81,56 @@ expect(config.context_data_deserializer).to eq(deserializer) expect(config.context_event_serializer).to eq(serializer) end + + it ".connect_timeout" do + config = described_class.create + config.connect_timeout = 5.0 + expect(config.connect_timeout).to eq(5.0) + end + + it ".connection_request_timeout" do + config = described_class.create + config.connection_request_timeout = 10.0 + expect(config.connection_request_timeout).to eq(10.0) + end + + it ".retry_interval" do + config = described_class.create + config.retry_interval = 1.0 + expect(config.retry_interval).to eq(1.0) + end + + it ".max_retries" do + config = described_class.create + config.max_retries = 3 + expect(config.max_retries).to eq(3) + end + + describe ".http_client_config" do + it "returns DefaultHttpClientConfig with custom values" do + config = described_class.create + config.connect_timeout = 5.0 + config.connection_request_timeout = 10.0 + config.retry_interval = 1.0 + config.max_retries = 3 + + http_config = config.http_client_config + expect(http_config).to be_a(DefaultHttpClientConfig) + expect(http_config.connect_timeout).to eq(5.0) + expect(http_config.connection_request_timeout).to eq(10.0) + expect(http_config.retry_interval).to eq(1.0) + expect(http_config.max_retries).to eq(3) + end + + it "returns DefaultHttpClientConfig with defaults when options not set" do + config = described_class.create + + http_config = config.http_client_config + expect(http_config).to be_a(DefaultHttpClientConfig) + expect(http_config.connect_timeout).to eq(3.0) + expect(http_config.connection_request_timeout).to eq(3.0) + expect(http_config.retry_interval).to eq(0.5) + expect(http_config.max_retries).to eq(5) + end + end end