Class: Faraday::HappyEyeballs::Adapter
- Inherits:
-
Adapter
- Object
- Adapter
- Faraday::HappyEyeballs::Adapter
- Defined in:
- lib/faraday/happy_eyeballs/adapter.rb
Constant Summary collapse
- NET_HTTP_REQUEST_CLASSES =
{ "GET" => Net::HTTP::Get, "POST" => Net::HTTP::Post, "PUT" => Net::HTTP::Put, "DELETE" => Net::HTTP::Delete, "PATCH" => Net::HTTP::Patch, "HEAD" => Net::HTTP::Head }.freeze
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app = nil, options = {}) ⇒ Adapter
constructor
A new instance of Adapter.
Constructor Details
#initialize(app = nil, options = {}) ⇒ Adapter
Returns a new instance of Adapter.
14 15 16 17 18 19 |
# File 'lib/faraday/happy_eyeballs/adapter.rb', line 14 def initialize(app = nil, = {}) super(app) @options = { connection_attempt_delay: 0.25, resolution_delay: 0.05, first_address_family_count: 1, connection_timeout: 10, cache_ttl: 300, prefer_ipv6: true, enable_cache: true }.merge() @connection_pool = ConnectionPool.new(@options) if @options[:enable_cache] @resolver = DualStackResolver.new(@options) end |
Instance Method Details
#call(env) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/faraday/happy_eyeballs/adapter.rb', line 21 def call(env) puts "=== HAPPY EYEBALLS ADAPTER CALLED ===" if ENV["DEBUG_HAPPYEYES"] == "true" puts "Original URL: #{env[:url]}" if ENV["DEBUG_HAPPYEYES"] == "true" uri = env[:url] # Extract connection details original_hostname = uri.hostname port = uri.port || (uri.scheme == "https" ? 443 : 80) puts "Resolving #{original_hostname}:#{port}" if ENV["DEBUG_HAPPYEYES"] == "true" begin connection_key = "#{original_hostname}:#{port}" successful_address = @connection_pool && @connection_pool.get_connection(connection_key) used_cached_address = !successful_address.nil? unless successful_address # Resolve addresses using your DualStackResolver addresses = @resolver.resolve_dual_stack(original_hostname) raise AllConnectionsFailed, "No addresses resolved for #{original_hostname}" if addresses.empty? sorted_addresses = sort_addresses(addresses) # Sort addresses according to preference successful_address = attempt_connections(sorted_addresses, port) # Attempt connections with Happy Eyeballs algorithm @connection_pool.cache_connection(connection_key, successful_address) if @connection_pool end begin make_request_with_address(env, successful_address, port) # Make the actual HTTP request with proper SNI rescue Faraday::ConnectionFailed # Only worth a fresh race if the failure came from a stale cached address. raise unless used_cached_address @connection_pool.clear_connection(connection_key) addresses = @resolver.resolve_dual_stack(original_hostname) raise AllConnectionsFailed, "No addresses resolved for #{original_hostname}" if addresses.empty? successful_address = attempt_connections(sort_addresses(addresses), port) @connection_pool.cache_connection(connection_key, successful_address) make_request_with_address(env, successful_address, port) end rescue AllConnectionsFailed, ConnectionTimeout => e raise Faraday::ConnectionFailed, e. rescue Timeout::Error raise Faraday::TimeoutError, "Connection timeout after #{@options[:connection_timeout]}s" end end |