def add_request(uri: nil, headers: {}, opts: {})
      fail ArgumentError, "uri must be a URI; got: #{uri}" unless uri.is_a?(URI)
      Request.new(uri, headers, @default_opts.merge(opts))
    end
def add_request(uri: nil, headers: {}, opts: {})
      fail ArgumentError, "uri must be a URI; got: #{uri}" unless uri.is_a?(URI)
      Request.new(uri, headers, @default_opts.merge(opts))
    end
Create a new asynchronous URL fetcher.

 @param opts [Hash] a hash of the supported options, which are:
 @option opts [Boolean] :follow_redirects  Whether to follow HTTP 3xx
   redirects.
 @option opts [Integer] :max_redirects Number of redirects to follow before
   giving up. (default: 10)
 @option opts [Boolean] :inline_exceptions If true, pass exceptions as a
   5xx response with the exception string in the body. (default: false)

 Run a request (in a new thread) and return a promise-like object for the
 response.

 @param uri [URI] the URI to be fetched
 @param headers [Hash<String, String>] HTTP headers to include with the
   request
 @param opts [Hash] options to override the ones provided when
   AsyncUriGetter was initialized. All supported options from `#initialize`
   are available here as well.