This project is archived and is in readonly mode.
ActiveResource timeout doesn't set open_timeout on underlying Net:HTTP object
ActiveResource provides a timeout variable: "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. "
However, the timeout value only sets the read_timeout on the underlying Net:HTTP object, not the open_timeout. This means that if a hostname resolves for an ActiveResource request, but there's no server to respond (or the server doesn't respond), the timeout value set in the ActiveResource subclass will not be adhered to. Modifying the ActiveResource::Connection class to also set the http object's open_timeout value should resolve the issue.
Comments and changes to this ticket
I can't create a patch, however i dug into this and here is what i've found.
We need to simply add the open_timeout to accept the timeout variable, so no additional functionality/arg's need to be changed in a person's app code. If they used timeout before, we simply take that same variable and apply it to Net::HTTP#opne_timeout, which is the variable you want to use if there is NO connection to a server. it appears the read_timeout variable is applied if you get a response but then nothing comes back, which as you can tell, is different then from being shut out of the server altogether.
Here is the code.
Line 139ish... http.open_timeout = @timeout ||= 60 #default to 60 seconds. currently default is never.
I've used the rdocs for Net::HTTP to verify the open_timeout method here:
open_timeout [RW] Seconds to wait until connection is opened. If the HTTP object cannot open a connection in this many seconds, it raises a TimeoutError exception.
Net::HTTP open_timeout doesn't have a default value however, it's set to nil == forever, so we set it to 60 seconds, to match the read_timeout variable's default in Net::HTTP.
Attached a patch to deal with this.
There's a couple of complications. Mainly, the 'http' method is what is building the Net::HTTP object. This would be fine, except that that lib/active_resource/http_mock overrides this entirely to use itself (ActiveResource::HttpMock). Considering this is kind of a public API, I didn't want to change the 'http' method, so instead, I created a 'build_http' method which handles the actual construction. I made a few tests which test that things happen sanely during build_http, including setting open_timeout.
I think some additional tests could be added for building the http object, but this should be enough for this particular issue.
- State changed from new to resolved
(from [a0caad5255ed120192755fce10960a38b53c056d]) Setting connection timeout also affects Net::HTTP open_timeout.
(from [83cc7de2a47df199348cc47d2794a3f30ad4f4fb]) Setting connection timeout also affects Net::HTTP open_timeout.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
Tickets have moved to Github
The new ticket tracker is available at https://github.com/rails/rails/issues