class PooledCurb

A Curb-based client which uses the “connection_pool” gem to allow high-performance HTTP requests in a multi-threaded environment.

Based on: github.com/karmi/tire-contrib/blob/master/lib/tire/http/clients/pooled_curb.rb

Example:


require 'pooled_curb'

Constants

POOL_SIZE
POOL_TIMEOUT
READ_TIMEOUT
RETRIES
RETRY_WAIT
VERSION
WRITE_TIMEOUT

Public Class Methods

configure() { |self| ... } click to toggle source
# File lib/pooled_curb.rb, line 27
def self.configure
  yield self

  self
end
connection_pool() click to toggle source
# File lib/pooled_curb.rb, line 43
def self.connection_pool
  @pool ||= ConnectionPool.new(connection_pool_opts) do |config|
    Curl::Easy.new
  end
end
delete(url, headers: {}) click to toggle source
# File lib/pooled_curb.rb, line 81
def self.delete(url, headers: {})
  perform_with_retry(:delete, url, timeout: _write_timeout, headers: headers)
end
disconnect!() click to toggle source
# File lib/pooled_curb.rb, line 49
def self.disconnect!
  if @pool
    @pool.shutdown { |client| client.close }
    @pool = nil
  end
end
get(url, headers: {}) click to toggle source
# File lib/pooled_curb.rb, line 64
def self.get(url, headers: {})
  perform_with_retry(:get, url, timeout: _read_timeout, headers: headers)
end
head(url, headers: {}) click to toggle source
# File lib/pooled_curb.rb, line 60
def self.head(url, headers: {})
  perform_with_retry(:head, url, timeout: _read_timeout, headers: headers)
end
multipart_form_post(url, data, headers: {}) click to toggle source
# File lib/pooled_curb.rb, line 72
def self.multipart_form_post(url, data, headers: {})
  perform_with_retry(:post, url, post_body: to_post_data(data), multipart_form_post: true, timeout: _write_timeout, headers: headers)
end
post(url, data, headers: {}) click to toggle source
# File lib/pooled_curb.rb, line 68
def self.post(url, data, headers: {})
  perform_with_retry(:post, url, post_body: to_post_data(data), timeout: _write_timeout, headers: headers)
end
put(url, data, headers: {}) click to toggle source
# File lib/pooled_curb.rb, line 76
def self.put(url, data, headers: {})

  perform_with_retry(:put, url, post_body: data, timeout: _write_timeout, headers: headers)
end
reset!() click to toggle source
# File lib/pooled_curb.rb, line 33
def self.reset!
  [:pool_size, :pool_timeout, :read_timeout, :write_timeout].each do |attr_name|
    send("#{attr_name}=", nil)
  end

  @pool = nil

  self
end
with_client(&block) click to toggle source
# File lib/pooled_curb.rb, line 56
def self.with_client(&block)
  connection_pool.with(&block)
end

Private Class Methods

_read_timeout() click to toggle source
# File lib/pooled_curb.rb, line 161
def self._read_timeout
  read_timeout || READ_TIMEOUT
end
_write_timeout() click to toggle source
# File lib/pooled_curb.rb, line 165
def self._write_timeout
  write_timeout || WRITE_TIMEOUT
end
connection_pool_opts() click to toggle source
# File lib/pooled_curb.rb, line 169
def self.connection_pool_opts
  {
    size: pool_size || POOL_SIZE,
    timeout: pool_timeout || POOL_TIMEOUT
  }
end
perform(verb, url, **opts) click to toggle source
# File lib/pooled_curb.rb, line 138
def self.perform(verb, url, **opts)
  with_client do |client|
    client.url = url

    opts.each do |attr, value|
      client.send("#{attr}=", value)
    end

    begin
      if [:put, :post].include?(verb)
        client.send("http_#{verb}", opts[:post_body])
      else
        client.send("http_#{verb}")
      end
      response = Response.new(client.response_code, client.header_str, client.body_str)
    rescue Curl::Err::CurlError
      # Reset the connection to prevent sending requests to the same broken handler
      client.close
      raise
    end
  end
end
perform_with_retry(verb, url, headers: {}, **opts) click to toggle source
# File lib/pooled_curb.rb, line 114
def self.perform_with_retry(verb, url, headers: {}, **opts)
  RETRIES.times do |tries|
    Kernel.sleep(RETRY_WAIT) if tries > 0
    can_retry = tries + 1 < RETRIES

    begin
      response = perform(verb, url, headers: headers, **opts)
      final_response = response.success? || (response.failure? && response.status < 500)

      return response if !can_retry || final_response
    rescue Curl::Err::CurlError => ex
      raise unless can_retry
    end
  end
end
to_post_data(data) click to toggle source
# File lib/pooled_curb.rb, line 130
def self.to_post_data(data)
  if data.kind_of?(Hash)
    data.map { |k, v| Curl::PostField.content(k, v) }
  else
    data
  end
end