What is the difference between timeout and open timeout?
You're reading the wrong documentation (yours is for wgibbs-rest-client which has not been updated since 2009): here's the right one. But that one does not say anything about the difference either, although it is simple:
:open_timeout
is the timeout for opening the connection. This is useful if you are calling servers with slow or shaky response times.
:timeout
is the timeout for reading the answer. This is useful to make sure you will not get stuck half way in the reading process, or get stuck reading a 5 MB file when you're expecting 5 KB of JSON
.
What is timeout and open timeout in Faraday?
If you look at the source code at https://github.com/lostisland/faraday/blob/master/lib/faraday/request.rb then you'll see:
# :timeout - open/read timeout Integer in seconds
# :open_timeout - read timeout Integer in seconds
Not very helpful, perhaps? Well, if you look at Faraday's Net::HTTP adapter at https://github.com/lostisland/faraday/blob/master/lib/faraday/adapter/net_http.rb, you'll see:
http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
http.open_timeout = req[:open_timeout] if req[:open_timeout]
So Faraday's open_timeout is equivalent to Net::HTTP's open_timeout which is documented as:
Number of seconds to wait for the connection to open. Any number may be used, including Floats for fractional seconds. If the HTTP object cannot open a connection in this many seconds, it raises a TimeoutError exception.
And Faraday's timeout is equivalent to Net::HTTP's read_timeout which is documented as:
Number of seconds to wait for one block to be read (via one read(2) call). Any number may be used, including Floats for fractional seconds. If the HTTP object cannot read data in this many seconds, it raises a TimeoutError exception.
If Net::HTTP's open_timeout and read_timeout are not set, will it wait indefinitely?
This actually means that server exists and accepts the request, but doesn’t return data, still keeping a connection open. Yes, in a case of such a malicious server the client will hang up.
There is no default timeout in Net::HTTP
. In normal scenario it will receive HTTPRequestTimeOut
response (which server is on duty of.) If you feel there might be any problem, you set the timeout yourself. But sometimes you really need to wait infinitely (server is processing large amount of data and you know it.)
Actually, I’d suggest it’s not a Net::HTTP problem
. Matz has already had problems with rb_wait_for_single_fd calls
. It actually looks like deadlock inside ruby thread synching, not like a server hangup.
How to tell a connect timeout error from a read timeout error in Ruby's Net::HTTP
Here's the solution (after Ben's fix):
require "net/http"
http = Net::HTTP.new("example.com")
http.open_timeout = 2
http.read_timeout = 3
begin
http.start
begin
http.request_get("/whatever?") do |res|
res.read_body
end
rescue Timeout::Error
puts "Timeout due to reading"
end
rescue Timeout::Error
puts "Timeout due to connecting"
end
How is Ruby TCPSocket timeout defined?
Use begin .. rescue Errno::ETIMEDOUT
to catch the timeout:
require 'socket'
begin
TCPSocket.new('www.example.com', 111)
rescue Errno::ETIMEDOUT
p 'timeout'
end
To catch any socket exceptions, use SystemCallError
instead.
According to the SystemCallError documentation:
SystemCallError is the base class for all low-level platform-dependent errors.
The errors available on the current platform are subclasses of
SystemCallError and are defined in the Errno module.
TCPSocket.new
does not support timeout directly.
Use Socket::connect_non_blocking
and IO::select
to set timeout.
require 'socket'
def connect(host, port, timeout = 5)
# Convert the passed host into structures the non-blocking calls
# can deal with
addr = Socket.getaddrinfo(host, nil)
sockaddr = Socket.pack_sockaddr_in(port, addr[0][4])
Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket|
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
begin
# Initiate the socket connection in the background. If it doesn't fail
# immediatelyit will raise an IO::WaitWritable (Errno::EINPROGRESS)
# indicating the connection is in progress.
socket.connect_nonblock(sockaddr)
rescue IO::WaitWritable
# IO.select will block until the socket is writable or the timeout
# is exceeded - whichever comes first.
if IO.select(nil, [socket], nil, timeout)
begin
# Verify there is now a good connection
socket.connect_nonblock(sockaddr)
rescue Errno::EISCONN
# Good news everybody, the socket is connected!
rescue
# An unexpected exception was raised - the connection is no good.
socket.close
raise
end
else
# IO.select returns nil when the socket is not ready before timeout
# seconds have elapsed
socket.close
raise "Connection timeout"
end
end
end
end
connect('www.example.com', 111, 2)
The above code comes from "Setting a Socket Connection Timeout in Ruby".
Rollbar Error processing the item: Net::OpenTimeout, execution expired
I have found the way to make it work. My final configuration is
Rollbar.reconfigure do |config|
config.access_token = ENV['ROLLBAR_TOKEN']
config.open_timeout = 15
config.request_timeout = 15
if %w(test development).include?(Rails.env)
config.enabled = false
end
end
the trick is to use reconfigure
instead of configure
otherwise it will not override the timeouts!
Related Topics
How to Convert an Octal Number to Decimal in Ruby
Trouble on Eager Loading "Second Degree" Associated Objects
Testing HTML5 File Upload with Capybara/Selenium Webdriver - Ruby
How to Handle Combination []+= for Auto-Vivifying Hash in Ruby
Does 'Upcase!' Not Mutate a Variable in Ruby
How to Force To_Yaml to Output Long Strings in Literal Block Style
Why Doesn't Array Override the Triple Equal Sign Method in Ruby
Official Expansion of ||= Conditional Assignment Operator
How to Serialize as Activesupport::Hashwithindifferentaccess Anymore
Can a Ruby Module Be Described as a Singleton Class
Access Local Variables from a Different Binding in Ruby
Nokogiri Returning Values as a String, Not an Array
Can Someone Explain the Following Code to Me