-
Notifications
You must be signed in to change notification settings - Fork 74
Replacing Timeout.timeout in Net::HTTP#connect with socket timeout options #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This was closed by #10, correct? |
yes it was. I've actually got equivalent pull requests at ruby/net-smtp#21, ruby/net-pop#3, and ruby/net-ftp#5, @deivid-rodriguez any chance I could get you to give those a quick code review? That seemed to be the impetus behind getting #10 accepted... |
Based on @hsbt's comment here, it sounds like we were waiting for In the context of this use case, is there a reason continuing to use |
As #74 says, |
Just to reiterate though, #set the nameserver to an address that doesnt exist, then run the following command:
bin $ time ./ruby -e 'require "net/http"; c = Net::HTTP.new("www.ffefecfceaefefxx.com"); c.open_timeout = 2; response = c.request_get("/"); puts response.code'
/Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1271:in `initialize': Failed to open TCP connection to www.ffefecfceaefefxx.com:80 (execution expired) (Net::OpenTimeout)
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1271:in `open'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1271:in `block in connect'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/timeout.rb:189:in `block in timeout'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/timeout.rb:196:in `timeout'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1269:in `connect'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1248:in `do_start'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1237:in `start'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1817:in `request'
from /Users/mohamed/.rvm/rubies/ruby-3.2.2/lib/ruby/3.2.0/net/http.rb:1727:in `request_get'
from -e:1:in `<main>'
real 0m30.106s
user 0m10.066s
sys 0m41.866s |
If you use Also see https://bugs.ruby-lang.org/issues/19430, that would solve it but it's not implemented yet. |
I have been investigating around this issue for improving net/http's Ractor support (context: https://bugs.ruby-lang.org/issues/21309). I'd like to see Since the time this ticket was opened, some things have changed and some things have not.
I have been thinking of ideas to replace
I'm under the impression that option (1) is the cleanest but not straightforward to implement. I'll try to learn if (3) is doable. |
Timeout.timeout
is inefficient because it spins up a new thread for each invocation, and can be unsafe (see https://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/ and http://blog.headius.com/2008/02/ruby-threadraise-threadkill-timeoutrb.html)Since we can set open timeouts on sockets now, it would be great to start doing that instead. I sent in a patch years ago, but it was rejected with the reasoning that without
Timeout.timeout
, there would be no way to time out the DNS lookup (https://bugs.ruby-lang.org/issues/12435).However, it turns out that Timeout.timeout can't time out the getaddrinfo C call in the first place! So the status quo is that the
open_timeout
option has no effect on the DNS lookup anyway! Either way we just have to wait for the operating system'sgetaddrinfo
call to time out on its own (30 seconds on MacOS 11.1), and settingopen_timeout
has no affect on that at all.That being the case, it would be great if we could drop the use of
Timeout.timeout
in favor of socket timeout options. I have a simple patch that is passing all tests, and would be happy to send in a pull request, but wanted to discuss a couple things first:To exactly mimic current behavior, we'd have to track the time used up in the DNS lookup, and subtract that from the timeout we give to open the socket. Is this worth it? Is it better done in the implementation of
Socket.tcp
?Should we take advantage of the
:resolv_timeout
available on systems withgetaddrinfo_a
(just Linux I believe?) for Ruby >= 2.7?The text was updated successfully, but these errors were encountered: