aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource/lib/active_resource
diff options
context:
space:
mode:
Diffstat (limited to 'activeresource/lib/active_resource')
-rw-r--r--activeresource/lib/active_resource/base.rb38
-rw-r--r--activeresource/lib/active_resource/connection.rb12
2 files changed, 46 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..3b61009f43 100644
--- a/activeresource/lib/active_resource/connection.rb
+++ b/activeresource/lib/active_resource/connection.rb
@@ -55,7 +55,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 +90,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 = {})
@@ -167,18 +172,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") } : {})