def make_request(verb, path, params = {}, type = nil, options = {})
      raise Exceptions::Terminating if state == :closed
      started_at = Time.now
      time_to_live = (options[:time_to_live] && options[:time_to_live] > 0) ? options[:time_to_live] : nil
      expires_at = started_at + [time_to_live || @options[:retry_timeout], @options[:retry_timeout]].min
      headers = time_to_live ? @auth_client.headers.merge("X-Expires-At" => started_at + time_to_live) : @auth_client.headers
      request_uuid = options[:request_uuid] || RightSupport::Data::UUID.generate
      attempts = 0
      result = nil
      @stats["requests sent"].measure(type || path, request_uuid) do
        begin
          attempts += 1
          http_options = {
            :open_timeout => @options[:open_timeout],
            :request_timeout => @options[:request_timeout],
            :request_uuid => request_uuid,
            :headers => headers }
          reconnect_once if (:disconnected == state) && !EM.reactor_running?
          raise Exceptions::ConnectivityFailure, "#{@type} client not connected" unless [:connected, :closing].include?(state)
          result = @http_client.send(verb, path, params, http_options.merge(options))
        rescue StandardError => e
          request_uuid = handle_exception(e, type || path, request_uuid, expires_at, attempts)
          request_uuid ? retry : raise
        end
      end
      @communicated_callbacks.each { |callback| callback.call } if @communicated_callbacks
      result
    end
def make_request(verb, path, params = {}, type = nil, options = {})
      raise Exceptions::Terminating if state == :closed
      started_at = Time.now
      time_to_live = (options[:time_to_live] && options[:time_to_live] > 0) ? options[:time_to_live] : nil
      expires_at = started_at + [time_to_live || @options[:retry_timeout], @options[:retry_timeout]].min
      headers = time_to_live ? @auth_client.headers.merge("X-Expires-At" => started_at + time_to_live) : @auth_client.headers
      request_uuid = options[:request_uuid] || RightSupport::Data::UUID.generate
      attempts = 0
      result = nil
      @stats["requests sent"].measure(type || path, request_uuid) do
        begin
          attempts += 1
          http_options = {
            :open_timeout => @options[:open_timeout],
            :request_timeout => @options[:request_timeout],
            :request_uuid => request_uuid,
            :headers => headers }
          reconnect_once if (:disconnected == state) && !EM.reactor_running?
          raise Exceptions::ConnectivityFailure, "#{@type} client not connected" unless [:connected, :closing].include?(state)
          result = @http_client.send(verb, path, params, http_options.merge(options))
        rescue StandardError => e
          request_uuid = handle_exception(e, type || path, request_uuid, expires_at, attempts)
          request_uuid ? retry : raise
        end
      end
      @communicated_callbacks.each { |callback| callback.call } if @communicated_callbacks
      result
    end
Make request via HTTP. Attempt to reconnect first if disconnected and EM reactor is not running.
 Rely on underlying HTTP client to log request and response.
 Retry request if response indicates to or if there are connectivity failures.

 There are also several timeouts involved:
   - Underlying BalancedHttpClient connection open timeout (:open_timeout)
   - Underlying BalancedHttpClient request timeout (:request_timeout)
   - Retry timeout for this method and its handlers (:retry_timeout)
   - Seconds before request expires and is to be ignored (:time_to_live)
 and if the target server is a RightNet router:
   - Router response timeout (ideally > :retry_timeout and < :request_timeout)
   - Router retry timeout (ideally = :retry_timeout)

 There are several possible levels of retry involved, starting with the outermost:
   - This method will retry if the targeted server is not responding or if it receives
     a retry response, but the total elapsed time is not allowed to exceed :request_timeout
   - RequestBalancer in BalancedHttpClient will retry using other endpoints if it gets an error
     that it considers retryable, and even if a front-end balancer is in use there will
     likely be at least two such endpoints for redundancy
 and if the target server is a RightNet router:
   - The router when sending a request via AMQP will retry if it receives no response,
     but not exceeding its configured :retry_timeout; if the router's timeouts for retry
     are consistent with the ones prescribed above, there will be no retry by the
     RequestBalancer after router retries

 @param [Symbol] verb for HTTP REST request
 @param [String] path in URI for desired resource
 @param [Hash] params for HTTP request
 @param [String] type of request for use in logging; defaults to path
 @param [String, NilClass] request_uuid uniquely identifying this request;
   defaults to randomly generated UUID
 @param [Numeric, NilClass] time_to_live seconds before request expires and is to be ignored;
   non-positive value or nil means never expire; defaults to nil
 @param [Hash] options augmenting or overriding default options for HTTP request

 @return [Object, NilClass] result of request with nil meaning no result

 @raise [Exceptions::Unauthorized] authorization failed
 @raise [Exceptions::ConnectivityFailure] cannot connect to server, lost connection
   to it, or it is out of service or too busy to respond
 @raise [Exceptions::RetryableError] request failed but if retried may succeed
 @raise [Exceptions::Terminating] closing client and terminating service
 @raise [Exceptions::InternalServerError] internal error in server being accessed