Skip to content

Replacing Timeout.timeout in Net::HTTP#connect with socket timeout options #6

Open
@mohamedhafez

Description

@mohamedhafez

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's getaddrinfo call to time out on its own (30 seconds on MacOS 11.1), and setting open_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:

  1. 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?

  2. Should we take advantage of the :resolv_timeout available on systems with getaddrinfo_a (just Linux I believe?) for Ruby >= 2.7?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions