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..29e4f25 100644 --- a/lib/getstream_ruby.rb +++ b/lib/getstream_ruby.rb @@ -12,12 +12,11 @@ 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:, **options) config = Configuration.manual( api_key: api_key, api_secret: api_secret, - base_url: base_url, - timeout: timeout, + **options, ) Client.new(config) end diff --git a/lib/getstream_ruby/client.rb b/lib/getstream_ruby/client.rb index d948b53..7604225 100644 --- a/lib/getstream_ruby/client.rb +++ b/lib/getstream_ruby/client.rb @@ -21,16 +21,15 @@ 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, **options) @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 || !options.empty? @configuration = Configuration.with_overrides( api_key: api_key, api_secret: api_secret, - base_url: base_url, - timeout: timeout, + **options, ) end @@ -131,12 +130,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..fa9bdb9 100644 --- a/lib/getstream_ruby/configuration.rb +++ b/lib/getstream_ruby/configuration.rb @@ -4,9 +4,21 @@ 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, 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 - def initialize(api_key: nil, api_secret: nil, base_url: nil, timeout: 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 +32,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.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' + else + connection_keep_alive + end @logger = nil end @@ -38,6 +57,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 +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) - new(api_key: api_key, api_secret: api_secret, - base_url: base_url, timeout: timeout, 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) @@ -63,6 +84,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..a9209ee 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