diff options
author | rick <rick@spacemonkey.local> | 2008-04-23 12:14:59 -0700 |
---|---|---|
committer | rick <rick@spacemonkey.local> | 2008-04-23 12:14:59 -0700 |
commit | eacb5cf0cab6447db78085c8bda6c94dd329ce6b (patch) | |
tree | df4bc7789c4d1fe83085b725be0d1fe4a6223880 /activeresource/lib | |
parent | 69d29e80f76079262f2e98e350592be1cfdfcd1e (diff) | |
parent | 6c1c16bfd9eb865dffa68c12c7df66d5a59a8714 (diff) | |
download | rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.tar.gz rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.tar.bz2 rails-eacb5cf0cab6447db78085c8bda6c94dd329ce6b.zip |
Merge branch 'master' of git@github.com:rails/rails
Diffstat (limited to 'activeresource/lib')
-rw-r--r-- | activeresource/lib/active_resource/base.rb | 38 | ||||
-rw-r--r-- | activeresource/lib/active_resource/connection.rb | 22 |
2 files changed, 56 insertions, 4 deletions
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index cd53c5d771..4072b9494d 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -166,6 +166,26 @@ module ActiveResource # # Learn more about Active Resource's validation features in the ActiveResource::Validations documentation. # + # === Timeouts + # + # Active Resource relies on HTTP to access RESTful APIs and as such is inherently susceptible to slow or + # unresponsive servers. In such cases, your Active Resource method calls could timeout. You can control the + # amount of time before Active Resource times out with the +timeout+ variable. + # + # class Person < ActiveResource::Base + # self.site = "http://api.people.com:3000/" + # self.timeout = 5 + # end + # + # This sets the +timeout+ to 5 seconds. You can adjust the timeout to a value suitable for the RESTful API + # you are accessing. It is recommended to set this to a reasonably low value to allow your Active Resource + # clients (especially if you are using Active Resource in a Rails application) to fail-fast (see + # http://en.wikipedia.org/wiki/Fail-fast) rather than cause cascading failures that could incapacitate your + # server. + # + # Internally, Active Resource relies on Ruby's Net::HTTP library to make HTTP requests. Setting +timeout+ + # sets the <tt>read_timeout</tt> of the internal Net::HTTP instance to the same value. The default + # <tt>read_timeout</tt> is 60 seconds on most Ruby implementations. class Base # The logger for diagnosing and tracing Active Resource calls. cattr_accessor :logger @@ -257,12 +277,27 @@ module ActiveResource write_inheritable_attribute("format", format) connection.format = format if site end - + # Returns the current format, default is ActiveResource::Formats::XmlFormat def format # :nodoc: read_inheritable_attribute("format") || ActiveResource::Formats[:xml] end + # Sets the number of seconds after which requests to the REST API should time out. + def timeout=(timeout) + @connection = nil + @timeout = timeout + end + + # Gets tthe number of seconds after which requests to the REST API should time out. + def timeout + if defined?(@timeout) + @timeout + elsif superclass != Object && superclass.timeout + superclass.timeout + end + end + # An instance of ActiveResource::Connection that is the base connection to the remote service. # The +refresh+ parameter toggles whether or not the connection is refreshed at every request # or not (defaults to <tt>false</tt>). @@ -271,6 +306,7 @@ module ActiveResource @connection = Connection.new(site, format) if refresh || @connection.nil? @connection.user = user if user @connection.password = password if password + @connection.timeout = timeout if timeout @connection else superclass.connection diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb index c8cee7aaa3..98b3f87167 100644 --- a/activeresource/lib/active_resource/connection.rb +++ b/activeresource/lib/active_resource/connection.rb @@ -18,6 +18,14 @@ module ActiveResource end end + # Raised when a Timeout::Error occurs. + class TimeoutError < ConnectionError + def initialize(message) + @message = message + end + def to_s; @message ;end + end + # 3xx Redirection class Redirection < ConnectionError # :nodoc: def to_s; response['Location'] ? "#{super} => #{response['Location']}" : super; end @@ -55,7 +63,7 @@ module ActiveResource # This class is used by ActiveResource::Base to interface with REST # services. class Connection - attr_reader :site, :user, :password + attr_reader :site, :user, :password, :timeout attr_accessor :format class << self @@ -90,6 +98,11 @@ module ActiveResource @password = password end + # Set the number of seconds after which HTTP requests to the remote service should time out. + def timeout=(timeout) + @timeout = timeout + end + # Execute a GET request. # Used to get (find) resources. def get(path, headers = {}) @@ -129,6 +142,8 @@ module ActiveResource time = Benchmark.realtime { result = http.send(method, path, *arguments) } logger.info "--> #{result.code} #{result.message} (#{result.body ? result.body : 0}b %.2fs)" % time if logger handle_response(result) + rescue Timeout::Error => e + raise TimeoutError.new(e.message) end # Handles response and error codes from remote service. @@ -167,18 +182,19 @@ module ActiveResource http = Net::HTTP.new(@site.host, @site.port) http.use_ssl = @site.is_a?(URI::HTTPS) http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl + http.read_timeout = @timeout if @timeout # If timeout is not set, the default Net::HTTP timeout (60s) is used. http end def default_header @default_header ||= { 'Content-Type' => format.mime_type } end - + # Builds headers for request to remote service. def build_request_headers(headers) authorization_header.update(default_header).update(headers) end - + # Sets authorization header def authorization_header (@user || @password ? { 'Authorization' => 'Basic ' + ["#{@user}:#{ @password}"].pack('m').delete("\r\n") } : {}) |