Setting a longer timeout for Net::HTTP Requests in Ruby
In order to exercise a RESTful web service I've been working on, I wrote a quick Ruby script to hammer the service with large update requests. After uncovering and fixing a handful of concurrency issues in the server, I started seeing timeout errors in my test script when I sent numerous simultaneous updates. The errors look like:
/opt/local/lib/ruby/1.8/timeout.rb:54:in `rbuf_fill': execution expired (Timeout::Error)
from /opt/local/lib/ruby/1.8/timeout.rb:56:in `timeout'
from /opt/local/lib/ruby/1.8/timeout.rb:76:in `timeout'
from /opt/local/lib/ruby/1.8/net/protocol.rb:132:in `rbuf_fill'
from /opt/local/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
from /opt/local/lib/ruby/1.8/net/protocol.rb:126:in `readline'
from /opt/local/lib/ruby/1.8/net/http.rb:2017:in `read_status_line'
from /opt/local/lib/ruby/1.8/net/http.rb:2006:in `read_new'
from /opt/local/lib/ruby/1.8/net/http.rb:1047:in `request'
from /opt/local/lib/ruby/1.8/net/http.rb:1034:in `request'
from /opt/local/lib/ruby/1.8/net/http.rb:543:in `start'
from /opt/local/lib/ruby/1.8/net/http.rb:1032:in `request'
from /opt/local/lib/ruby/1.8/net/http.rb:842:in `post'
from ./rndsender.rb:21:in `post_update'
from ./rndsender.rb:76:in `main'
from ./rndsender.rb:80
Adding a rescue as shown below allows you to handle the timeout error:
def post_update(path, payload)
http = Net::HTTP.new(@host, @port)
res = http.post(path, payload, {'Content-Type' =>; 'application/xml'})
case res
when Net::HTTPSuccess
puts "update posted"
else
res.error!
end
rescue Timeout::Error =>; e
puts "update timeout error"
end
After searching a bit on the web, I came across this post that had the magic incantation for adjusting the timeout in the Net::HTTP API. Here it is:
http = Net::HTTP.new(@host, @port) http.read_timeout = 500
And in case you are interested in actually making use of the timeout, be warned! Read this in which you will learn that
Ruby's Thread#raise, Thread#kill, and the timeout.rb standard library based on them are inherently broken and should not be used for any purpose. And by extension, net/protocol.rb and all the net/* libraries that use timeout.rb are also currently broken (but they can be fixed).
Technorati Tags: programming, Ruby
archived on 2008-04-13 in null
blog comments powered by Disqus
