From 1ff7aadac8f6e0bd99e9222b721bca39cbe7e555 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Mon, 11 May 2026 13:05:26 +0200 Subject: [PATCH 1/2] fix: add configurable keep-alive and Faraday adapter options Expose optional HTTP connection settings so SDK users can tune latency behavior without changing default adapter semantics. This keeps existing behavior intact while enabling adapter-level connection reuse configuration. Co-authored-by: Cursor --- README.md | 14 ++++++++++++++ lib/getstream_ruby.rb | 6 +++++- lib/getstream_ruby/client.rb | 23 ++++++++++++++++++++--- lib/getstream_ruby/configuration.rb | 28 ++++++++++++++++++++++++---- spec/getstream_ruby_spec.rb | 18 ++++++++++++++++++ 5 files changed, 81 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 7a914ad..5cd4b6e 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,23 @@ require 'getstream_ruby' client = GetStreamRuby.manual( api_key: "your_api_key", api_secret: "your_api_secret", + # Optional HTTP tuning for keep-alive / connection reuse + connection_keep_alive: true, + # Optional: bring your own Faraday adapter (default is Faraday.default_adapter) + faraday_adapter: :net_http, + faraday_adapter_options: { + # adapter-specific options + } ) ``` +You can also set these via environment variables: + +```bash +STREAM_CONNECTION_KEEP_ALIVE=true +STREAM_FARADAY_ADAPTER=net_http +``` + ### Method 2: .env File Create a `.env` file in your project root: diff --git a/lib/getstream_ruby.rb b/lib/getstream_ruby.rb index 468e4bf..b34537f 100644 --- a/lib/getstream_ruby.rb +++ b/lib/getstream_ruby.rb @@ -12,12 +12,16 @@ module GetStreamRuby class << self # Method 1: Manual configuration (highest priority) - def manual(api_key:, api_secret:, base_url: nil, timeout: nil) + def manual(api_key:, api_secret:, base_url: nil, timeout: nil, faraday_adapter: nil, + faraday_adapter_options: nil, connection_keep_alive: nil) config = Configuration.manual( api_key: api_key, api_secret: api_secret, base_url: base_url, timeout: timeout, + faraday_adapter: faraday_adapter, + faraday_adapter_options: faraday_adapter_options, + connection_keep_alive: connection_keep_alive, ) Client.new(config) end diff --git a/lib/getstream_ruby/client.rb b/lib/getstream_ruby/client.rb index d948b53..08112ef 100644 --- a/lib/getstream_ruby/client.rb +++ b/lib/getstream_ruby/client.rb @@ -21,16 +21,21 @@ class Client attr_reader :configuration - def initialize(config = nil, api_key: nil, api_secret: nil, base_url: nil, timeout: nil) + def initialize(config = nil, api_key: nil, api_secret: nil, base_url: nil, timeout: nil, faraday_adapter: nil, + faraday_adapter_options: nil, connection_keep_alive: nil) @configuration = config || GetStreamRuby.configuration # Create new configuration with overrides if any parameters provided - if api_key || api_secret || base_url || timeout + if api_key || api_secret || base_url || timeout || faraday_adapter || faraday_adapter_options || + !connection_keep_alive.nil? @configuration = Configuration.with_overrides( api_key: api_key, api_secret: api_secret, base_url: base_url, timeout: timeout, + faraday_adapter: faraday_adapter, + faraday_adapter_options: faraday_adapter_options, + connection_keep_alive: connection_keep_alive, ) end @@ -131,12 +136,24 @@ def build_connection backoff_factor: 2, } conn.response :json, content_type: /\bjson$/ - conn.adapter Faraday.default_adapter + conn.headers['Connection'] = 'keep-alive' if @configuration.connection_keep_alive + configure_adapter(conn) conn.options.timeout = @configuration.timeout end end + def configure_adapter(connection) + adapter = @configuration.faraday_adapter || Faraday.default_adapter + adapter_options = @configuration.faraday_adapter_options || {} + connection.adapter(adapter, **adapter_options) + rescue Faraday::Error, ArgumentError => e + @configuration.logger&.warn( + "Falling back to #{Faraday.default_adapter}: could not use adapter #{adapter} (#{e.message})", + ) + connection.adapter Faraday.default_adapter + end + def generate_auth_header JWT.encode( { diff --git a/lib/getstream_ruby/configuration.rb b/lib/getstream_ruby/configuration.rb index a22ce18..8f729ea 100644 --- a/lib/getstream_ruby/configuration.rb +++ b/lib/getstream_ruby/configuration.rb @@ -4,9 +4,11 @@ module GetStreamRuby class Configuration - attr_accessor :api_key, :api_secret, :base_url, :timeout, :logger + attr_accessor :api_key, :api_secret, :base_url, :timeout, :logger, :faraday_adapter, :faraday_adapter_options, + :connection_keep_alive - def initialize(api_key: nil, api_secret: nil, base_url: nil, timeout: nil, use_env: true) + def initialize(api_key: nil, api_secret: nil, base_url: nil, timeout: nil, faraday_adapter: nil, + faraday_adapter_options: nil, connection_keep_alive: nil, use_env: true) if use_env @api_key = api_key || ENV.fetch('STREAM_API_KEY', nil) @api_secret = api_secret || ENV.fetch('STREAM_API_SECRET', nil) @@ -20,6 +22,13 @@ def initialize(api_key: nil, api_secret: nil, base_url: nil, timeout: nil, use_e @timeout = timeout || 30 end + @faraday_adapter = (faraday_adapter || ENV['STREAM_FARADAY_ADAPTER'])&.to_sym + @faraday_adapter_options = faraday_adapter_options || default_adapter_options + @connection_keep_alive = if connection_keep_alive.nil? + ENV.fetch('STREAM_CONNECTION_KEEP_ALIVE', 'true') == 'true' + else + connection_keep_alive + end @logger = nil end @@ -38,6 +47,9 @@ def dup api_secret: @api_secret, base_url: @base_url, timeout: @timeout, + faraday_adapter: @faraday_adapter, + faraday_adapter_options: @faraday_adapter_options.dup, + connection_keep_alive: @connection_keep_alive, ) end @@ -47,9 +59,11 @@ def self.with_overrides(overrides = {}) end # Method 1: Manual configuration (no environment variables) - def self.manual(api_key:, api_secret:, base_url: nil, timeout: nil) + def self.manual(api_key:, api_secret:, base_url: nil, timeout: nil, faraday_adapter: nil, + faraday_adapter_options: nil, connection_keep_alive: nil) new(api_key: api_key, api_secret: api_secret, - base_url: base_url, timeout: timeout, use_env: false) + base_url: base_url, timeout: timeout, faraday_adapter: faraday_adapter, + faraday_adapter_options: faraday_adapter_options, connection_keep_alive: connection_keep_alive, use_env: false) end # Method 2: .env file (loads .env file via dotenv gem, falls back to env vars) @@ -63,6 +77,12 @@ def self.from_system_env new(use_env: true) end + private + + def default_adapter_options + {} + end + end end diff --git a/spec/getstream_ruby_spec.rb b/spec/getstream_ruby_spec.rb index b4a18f3..de6d41b 100644 --- a/spec/getstream_ruby_spec.rb +++ b/spec/getstream_ruby_spec.rb @@ -23,6 +23,24 @@ expect(client).to be_a(GetStreamRuby::Client) expect(client.configuration.api_key).to eq('manual_key') expect(client.configuration.api_secret).to eq('manual_secret') + 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) + + end + + it 'creates a client with custom faraday adapter settings' do + + client = GetStreamRuby.manual( + api_key: 'manual_key', + api_secret: 'manual_secret', + faraday_adapter: :net_http, + faraday_adapter_options: {}, + connection_keep_alive: false, + ) + expect(client.configuration.faraday_adapter).to eq(:net_http) + expect(client.configuration.faraday_adapter_options).to eq({}) + expect(client.configuration.connection_keep_alive).to eq(false) end From af3efbd6ad7732116ab220c5ac6aad4b22489933 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Mon, 11 May 2026 13:10:07 +0200 Subject: [PATCH 2/2] fix: reduce keyword parameter list size for rubocop Refactor manual/client/configuration signatures to accept option hashes so Metrics/ParameterLists passes while preserving existing keyword compatibility for HTTP connection settings. Co-authored-by: Cursor --- lib/getstream_ruby.rb | 9 ++------- lib/getstream_ruby/client.rb | 12 +++--------- lib/getstream_ruby/configuration.rb | 23 +++++++++++++++-------- spec/getstream_ruby_spec.rb | 2 +- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/getstream_ruby.rb b/lib/getstream_ruby.rb index b34537f..29e4f25 100644 --- a/lib/getstream_ruby.rb +++ b/lib/getstream_ruby.rb @@ -12,16 +12,11 @@ module GetStreamRuby class << self # Method 1: Manual configuration (highest priority) - def manual(api_key:, api_secret:, base_url: nil, timeout: nil, faraday_adapter: nil, - faraday_adapter_options: nil, connection_keep_alive: nil) + def manual(api_key:, api_secret:, **options) config = Configuration.manual( api_key: api_key, api_secret: api_secret, - base_url: base_url, - timeout: timeout, - faraday_adapter: faraday_adapter, - faraday_adapter_options: faraday_adapter_options, - connection_keep_alive: connection_keep_alive, + **options, ) Client.new(config) end diff --git a/lib/getstream_ruby/client.rb b/lib/getstream_ruby/client.rb index 08112ef..7604225 100644 --- a/lib/getstream_ruby/client.rb +++ b/lib/getstream_ruby/client.rb @@ -21,21 +21,15 @@ class Client attr_reader :configuration - def initialize(config = nil, api_key: nil, api_secret: nil, base_url: nil, timeout: nil, faraday_adapter: nil, - faraday_adapter_options: nil, connection_keep_alive: nil) + def initialize(config = nil, api_key: nil, api_secret: nil, **options) @configuration = config || GetStreamRuby.configuration # Create new configuration with overrides if any parameters provided - if api_key || api_secret || base_url || timeout || faraday_adapter || faraday_adapter_options || - !connection_keep_alive.nil? + if api_key || api_secret || !options.empty? @configuration = Configuration.with_overrides( api_key: api_key, api_secret: api_secret, - base_url: base_url, - timeout: timeout, - faraday_adapter: faraday_adapter, - faraday_adapter_options: faraday_adapter_options, - connection_keep_alive: connection_keep_alive, + **options, ) end diff --git a/lib/getstream_ruby/configuration.rb b/lib/getstream_ruby/configuration.rb index 8f729ea..fa9bdb9 100644 --- a/lib/getstream_ruby/configuration.rb +++ b/lib/getstream_ruby/configuration.rb @@ -7,8 +7,18 @@ class Configuration attr_accessor :api_key, :api_secret, :base_url, :timeout, :logger, :faraday_adapter, :faraday_adapter_options, :connection_keep_alive - def initialize(api_key: nil, api_secret: nil, base_url: nil, timeout: nil, faraday_adapter: nil, - faraday_adapter_options: nil, connection_keep_alive: nil, use_env: true) + def initialize(api_key: nil, api_secret: nil, use_env: true, **options) + base_url = options[:base_url] + timeout = options[:timeout] + http_options = options[:http_options] || {} + faraday_adapter = options[:faraday_adapter] || http_options[:faraday_adapter] + faraday_adapter_options = options[:faraday_adapter_options] || http_options[:faraday_adapter_options] + connection_keep_alive = if options.key?(:connection_keep_alive) + options[:connection_keep_alive] + else + http_options[:connection_keep_alive] + end + if use_env @api_key = api_key || ENV.fetch('STREAM_API_KEY', nil) @api_secret = api_secret || ENV.fetch('STREAM_API_SECRET', nil) @@ -22,7 +32,7 @@ def initialize(api_key: nil, api_secret: nil, base_url: nil, timeout: nil, farad @timeout = timeout || 30 end - @faraday_adapter = (faraday_adapter || ENV['STREAM_FARADAY_ADAPTER'])&.to_sym + @faraday_adapter = (faraday_adapter || ENV.fetch('STREAM_FARADAY_ADAPTER', nil))&.to_sym @faraday_adapter_options = faraday_adapter_options || default_adapter_options @connection_keep_alive = if connection_keep_alive.nil? ENV.fetch('STREAM_CONNECTION_KEEP_ALIVE', 'true') == 'true' @@ -59,11 +69,8 @@ def self.with_overrides(overrides = {}) end # Method 1: Manual configuration (no environment variables) - def self.manual(api_key:, api_secret:, base_url: nil, timeout: nil, faraday_adapter: nil, - faraday_adapter_options: nil, connection_keep_alive: nil) - new(api_key: api_key, api_secret: api_secret, - base_url: base_url, timeout: timeout, faraday_adapter: faraday_adapter, - faraday_adapter_options: faraday_adapter_options, connection_keep_alive: connection_keep_alive, use_env: false) + def self.manual(api_key:, api_secret:, **options) + new(api_key: api_key, api_secret: api_secret, use_env: false, **options) end # Method 2: .env file (loads .env file via dotenv gem, falls back to env vars) diff --git a/spec/getstream_ruby_spec.rb b/spec/getstream_ruby_spec.rb index de6d41b..a9209ee 100644 --- a/spec/getstream_ruby_spec.rb +++ b/spec/getstream_ruby_spec.rb @@ -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) - + end it 'creates a client with custom faraday adapter settings' do