Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handful of performance optimizations #48

Merged
merged 5 commits into from
Apr 14, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions lib/ethon/easy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,11 @@ def initialize(options = {})
# @see initialize
def set_attributes(options)
options.each_pair do |key, value|
unless respond_to?("#{key}=")
method = "#{key}="
unless respond_to?(method)
raise Errors::InvalidOption.new(key)
end
method("#{key}=").call(value)
send(method, value)
end
end

Expand All @@ -244,7 +245,7 @@ def set_attributes(options)
def reset
@url = nil
@hash = nil
@on_complete = []
@on_complete = nil
Curl.easy_reset(handle)
set_callbacks
end
Expand Down Expand Up @@ -278,7 +279,7 @@ def to_hash
:response_body => response_body
}
Easy::Informations::AVAILABLE_INFORMATIONS.keys.each do |info|
@hash[info] = method(info).call
@hash[info] = send(info)
end
@hash
end
Expand All @@ -296,7 +297,7 @@ def log_inspect
:return_code => return_code,
:total_time => total_time
}
"EASY #{hash.map{|k, v| "#{k}=#{v}"}.flatten.join(' ')}"
"EASY #{hash.map!{|k, v| "#{k}=#{v}"}.flatten.join(' ')}"
end
end
end
4 changes: 1 addition & 3 deletions lib/ethon/easy/informations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ module Informations
}

AVAILABLE_INFORMATIONS.each do |name, type|
define_method(name) do
Curl.method("get_info_#{type}").call(name, handle)
end
eval %Q|def #{name}; Curl.send(:get_info_#{type}, :#{name}, handle); end|
end

# Returns this curl version supports zlib.
Expand Down
2 changes: 1 addition & 1 deletion lib/ethon/easy/operations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def handle
def perform
@return_code = Curl.easy_perform(handle)
complete
Ethon.logger.debug("ETHON: performed #{self.log_inspect}")
Ethon.logger.debug { "ETHON: performed #{self.log_inspect}" }
@return_code
end

Expand Down
26 changes: 22 additions & 4 deletions lib/ethon/easy/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -522,11 +522,29 @@ def postfieldsize=(value)
Curl.set_option(:postfieldsize, value_for(value, :int), handle)
end

# Pass a bitmask to control how libcurl acts on redirects after
# POSTs that get a 301, 302 or 303 response back. A parameter
# with bit 0 set (value CURL_REDIR_POST_301) tells the library
# to respect RFC 2616/10.3.2 and not convert POST requests into
# GET requests when following a 301 redirection. Setting bit 1
# (value CURL_REDIR_POST_302) makes libcurl maintain the request
# method after a 302 redirect whilst setting bit 2 (value
# CURL_REDIR_POST_303) makes libcurl maintain the request method
# after a 303 redirect. The value CURL_REDIR_POST_ALL is a
# convenience define that sets all three bits.
#
# The non-RFC behaviour is ubiquitous in web browsers, so the
# library does the conversion by default to maintain
# consistency. However, a server may require a POST to remain a
# POST after such a redirection. This option is meaningful only
# when setting CURLOPT_FOLLOWLOCATION. (Added in 7.17.1) (This
# option was known as CURLOPT_POST301 up to 7.19.0 as it only
# supported the 301 then)
#
# @example Set postredir option.
# easy.postredir = :post_all
#
# @example Set protocols option.
# easy.protocols = :http
#
# @param [ Symbol ] value The value or array of values to set.
# @param [ Symbol ] value The value to set.
#
# @return [ void ]
def postredir=(value)
Expand Down
47 changes: 25 additions & 22 deletions lib/ethon/easy/queryable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ def empty?
#
# @return [ String ] The string representation.
def to_s
query_pairs.map{ |pair|
@to_s ||= query_pairs.map{ |pair|
return pair if pair.is_a?(String)

pair.map{ |e|
escape && @easy ? @easy.escape(e.to_s) : e
}.join("=")
if escape && @easy
pair.map{ |e| @easy.escape(e.to_s) }.join("=")
else
pair.join("=")
end
}.join('&')
end

Expand All @@ -59,21 +61,7 @@ def build_query_pairs(hash)
return [hash] if hash.is_a?(String)

pairs = []
recursive = Proc.new do |h, prefix|
case h
when Hash
h.each_pair do |k,v|
key = prefix == '' ? k : "#{prefix}[#{k}]"
pairs_for(v, key, pairs, recursive)
end
when Array
h.each_with_index do |v, i|
key = "#{prefix}[#{i}]"
pairs_for(v, key, pairs, recursive)
end
end
end
recursive.call(hash, '')
recursively_generate_pairs(hash, nil, pairs)
pairs
end

Expand All @@ -97,12 +85,27 @@ def file_info(file)

private

def pairs_for(v, key, pairs, recursive)
def recursively_generate_pairs(h, prefix, pairs)
case h
when Hash
h.each_pair do |k,v|
key = prefix.nil? ? k : "#{prefix}[#{k}]"
pairs_for(v, key, pairs)
end
when Array
h.each_with_index do |v, i|
key = "#{prefix}[#{i}]"
pairs_for(v, key, pairs)
end
end
end

def pairs_for(v, key, pairs)
case v
when Hash
recursive.call(v, key)
recursively_generate_pairs(v, key, pairs)
when Array
recursive.call(v, key)
recursively_generate_pairs(v, key, pairs)
when File, Tempfile
pairs << [Util.escape_zero_byte(key), file_info(v)]
else
Expand Down
2 changes: 1 addition & 1 deletion lib/ethon/easy/response_callbacks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def on_complete(&block)
# request.complete
def complete
if defined?(@on_complete)
@on_complete.map{ |callback| callback.call(self) }
@on_complete.each{ |callback| callback.call(self) }
end
end
end
Expand Down
9 changes: 6 additions & 3 deletions lib/ethon/multi/operations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module Ethon
class Multi # :nodoc
# This module contains logic to run a multi.
module Operations
STARTED_MULTI = "ETHON: started MULTI"
PERFORMED_MULTI = "ETHON: performed MULTI"

# Return the multi handle. Inititialize multi handle,
# in case it didn't happened already.
#
Expand Down Expand Up @@ -35,15 +38,15 @@ def init_vars
# @example Perform multi.
# multi.perform
def perform
Ethon.logger.debug("ETHON: started MULTI")
Ethon.logger.debug(STARTED_MULTI)
while ongoing?
run
timeout = get_timeout
next if timeout == 0
reset_fds
set_fds(timeout)
end
Ethon.logger.debug("ETHON: performed MULTI")
Ethon.logger.debug(PERFORMED_MULTI)
nil
end

Expand Down Expand Up @@ -140,7 +143,7 @@ def check
next if msg[:code] != :done
easy = easy_handles.find{ |e| e.handle == msg[:easy_handle] }
easy.return_code = msg[:data][:code]
Ethon.logger.debug("ETHON: performed #{easy.log_inspect}")
Ethon.logger.debug { "ETHON: performed #{easy.log_inspect}" }
delete(easy)
easy.complete
end
Expand Down