class Dodgeball::Client::Request

Attributes

stub[W]

Public Class Methods

new(options = {}) click to toggle source

public: Creates a new request object to send dodgeball api request

# File lib/dodgeball/client/request.rb, line 24
def initialize(options = {})
  options[:host] ||= HOST
  options[:port] ||= PORT

  options[:ssl] ||= SSL

  @headers = options[:headers] || HEADERS
  @retries = options[:retries] || RETRIES
  @backoff_policy =
    options[:backoff_policy] || Dodgeball::Client::BackoffPolicy.new

  uri = URI(options[:dodgeball_api_url] || DODGEBALL_API_URL)

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = options[:ssl]
  http.read_timeout = DEFAULT_READ_TIMEOUT
  http.open_timeout = DEFAULT_OPEN_TIMEOUT

  @http = http
end

Private Class Methods

stub() click to toggle source
# File lib/dodgeball/client/request.rb, line 137
def stub
  @stub || ENV['STUB']
end

Public Instance Methods

post(write_key, path, request_body, request_specific_headers=nil) click to toggle source

public: Posts the write key and path to the API.

returns - Response of the status and error if it exists

# File lib/dodgeball/client/request.rb, line 49
def post(write_key, path, request_body, request_specific_headers=nil)

 last_response, exception = retry_with_backoff(@retries) do
    status_code, response_body = send_request(write_key, path, request_body, request_specific_headers)
    should_retry = should_retry_request?(status_code, response_body)
    logger.debug("Response status code: #{status_code}")
    logger.debug("Response response body: #{response_body}") if response_body

    [Response.new(status_code, response_body), should_retry]
  end

  if exception      
    logger.error(exception.message)
    puts "E #{exception.message}"
    exception.backtrace.each { |line| logger.error(line) }
    Response.new(-1, exception.to_s)
  else
    last_response
  end
end

Private Instance Methods

retry_with_backoff(retries_remaining) { || ... } click to toggle source

Takes a block that returns [result, should_retry].

Retries upto ‘retries_remaining` times, if `should_retry` is false or an exception is raised. `@backoff_policy` is used to determine the duration to sleep between attempts

Returns [last_result, raised_exception]

# File lib/dodgeball/client/request.rb, line 92
def retry_with_backoff(retries_remaining, &block)
  result, caught_exception = nil
  should_retry = false

  begin
    result, should_retry = yield
    return [result, nil] unless should_retry
  rescue StandardError => e
    should_retry = true
    caught_exception = e
  end

  if should_retry && (retries_remaining > 1)
    logger.debug("Retrying request, #{retries_remaining} retries left")
    sleep(@backoff_policy.next_interval.to_f / 1000)
    retry_with_backoff(retries_remaining - 1, &block)
  else
    [result, caught_exception]
  end
end
send_request(write_key, path, body, request_specific_headers) click to toggle source

Sends a request to the path, returns [status_code, body]

# File lib/dodgeball/client/request.rb, line 114
def send_request(write_key, path, body, request_specific_headers)

  payload = JSON.generate(body) if body
  
  request_headers =(@headers || {}).merge(request_specific_headers || {})
  request_headers[SECRET_KEY_HEADER] = write_key
  request = Net::HTTP::Post.new(path, request_headers)
  
  if self.class.stub
    logger.debug "stubbed request to #{path}: " \
      "write key = #{write_key}, payload = #{payload}"

    [200, '{}']
  else
    puts payload
    response = @http.request(request, payload)
    [response.code.to_i, response.body]
  end
end
should_retry_request?(status_code, body) click to toggle source
# File lib/dodgeball/client/request.rb, line 72
def should_retry_request?(status_code, body)
  if status_code >= 500
    true # Server error
  elsif status_code == 429
    true # Rate limited
  elsif status_code >= 400
    logger.error(body)
    false # Client error. Do not retry, but log
  else
    false
  end
end