Again alias_method_chain. Simple and elegant (I think) way to add retry functionality to curl based screen scraper
require 'curb'
module Extend::Curl
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
#optional parameters
def with_curl_retry(method_name, opts={})
opts.reverse_merge!(:try => 2, :sleep => 2, :error => StandardError)
error_attribute_name = "#{method_name}_with_curl_retry_error"
write_inheritable_attribute(error_attribute_name, opts[:error])
src_code= <<-CODE
def #{method_name.to_s}_with_curl_retry(*args)
num_tries = #{opts[:try]}
begin
return #{method_name.to_s}_without_curl_retry(*args)
rescue Curl::Err::CurlError => e
num_tries -= 1
retry if num_tries > 0 && sleep(#{opts[:sleep]})
raise self.class.read_inheritable_attribute("#{error_attribute_name}")
end
end
alias_method_chain :#{method_name.to_s}, :curl_retry unless method_defined?(:#{method_name.to_s}_without_curl_retry)
CODE
class_eval src_code
end
end
end
and then in your code
class SuperScreenScraper
def do_some_scraping(a,b,c)
...
end
include Extend::Curl
#try 3 times and sleep 1 second in between tries
with_curl_retry :do_some_scraping, :sleep => 1, :try => 3
end