[#113107] [Ruby master Bug#19576] Backport request: Gemfile.lock resolving is broken with bundler shipped with Ruby 3.1.4 — "jprokop (Jarek Prokop) via ruby-core" <ruby-core@...>

Issue #19576 has been reported by jprokop (Jarek Prokop).

8 messages 2023/04/04

[#113112] [Ruby master Bug#19578] abort() shows stack trace when run within rescue clause — "Dan0042 (Daniel DeLorme) via ruby-core" <ruby-core@...>

Issue #19578 has been reported by Dan0042 (Daniel DeLorme).

8 messages 2023/04/04

[#113180] [Ruby master Feature#19588] Allow Comparable#clamp(min, max) to accept nil as a specification — "kyanagi (Kouhei Yanagita) via ruby-core" <ruby-core@...>

Issue #19588 has been reported by kyanagi (Kouhei Yanagita).

7 messages 2023/04/11

[#113209] [Ruby master Bug#19596] Decreased performance after upgrading from ruby 2.7.2 to ruby 3.2.2 — silva96 via ruby-core <ruby-core@...>

Issue #19596 has been reported by silva96 (Benjam=EDn Silva).

7 messages 2023/04/13

[#113238] [Ruby master Misc#19599] DevMeeting-2023-05-10 — "mame (Yusuke Endoh) via ruby-core" <ruby-core@...>

Issue #19599 has been reported by mame (Yusuke Endoh).

14 messages 2023/04/14

[#113285] [Ruby master Bug#19607] Introduce `Hash#symbolize_keys`. — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

Issue #19607 has been reported by ioquatix (Samuel Williams).

8 messages 2023/04/18

[#113303] [Ruby master Feature#19610] GC.delay_promotion — "peterzhu2118 (Peter Zhu) via ruby-core" <ruby-core@...>

Issue #19610 has been reported by peterzhu2118 (Peter Zhu).

9 messages 2023/04/20

[#113313] [Ruby master Bug#19613] Add version information to all function documentation — "fulldecent (William Entriken) via ruby-core" <ruby-core@...>

Issue #19613 has been reported by fulldecent (William Entriken).

7 messages 2023/04/23

[#113342] [Ruby master Feature#19617] Add Method#binding and UnboundMethod#binding, similar to Proc#binding — "nevans (Nicholas Evans) via ruby-core" <ruby-core@...>

Issue #19617 has been reported by nevans (Nicholas Evans).

9 messages 2023/04/25

[#113381] [Ruby master Bug#19624] Backticks - IO object leakage — pineman via ruby-core <ruby-core@...>

Issue #19624 has been reported by pineman (Jo=E3o Pinheiro).

10 messages 2023/04/30

[ruby-core:113145] [Ruby master Feature#19430] Contribution wanted: DNS lookup by c-ares library

From: "kzys (Kazuyoshi Kato) via ruby-core" <ruby-core@...>
Date: 2023-04-06 04:32:27 UTC
List: ruby-core #113145
Issue #19430 has been updated by kzys (Kazuyoshi Kato).


Hello. I'm interested to take a look, but new to Ruby's development.

Is it acceptable to make the PoC merge-able first and work on macOS and per-platform resolvers later? Not really sure changing the c-ares for macOS (as below) is more straightforward, compared to pthread + getaddrinfo approach. The pthread takes more resources (namely threads), but works as a nice fallback for other OSes.

https://github.com/c-ares/c-ares/issues/330#issuecomment-655238093

> We'd probably accept patches to add such support for MacOS, but it is definitely not on any development roadmap.

----------------------------------------
Feature #19430: Contribution wanted: DNS lookup by c-ares library
https://bugs.ruby-lang.org/issues/19430#change-102680

* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
----------------------------------------
## Problem

At the present time, Ruby uses `getaddrinfo(3)` to resolve names. Because this function is synchronous, we cannot interrupt the thread performing name resolution until the DNS server returns a response.

We can see this behavior by setting blackhole.webpagetest.org (72.66.115.13) as a DNS server, which swallows all packets, and resolving any name:

```
# cat /etc/resolv.conf
nameserver 72.66.115.13

# ./local/bin/ruby -rsocket -e 'Addrinfo.getaddrinfo("www.ruby-lang.org", 80)'
^C^C^C^C
```

As we see, Ctrl+C does not stop ruby.

The current workaround that users can take is to do name resolution in a Ruby thread.

```ruby
Thread.new { Addrinfo.getaddrinfo("www.ruby-lang.org", 80) }.value
```

The thread that calls this code is interruptible. (Note that the newly created thread itself will be stuck until the DNS lookup exceeds the time out.)

## Proposal

We can solve this problem by using c-ares, which is an asynchronous name resolver, as a backend of `Addrinfo.getaddrinfo`, etc. (@sorah told me about this library, thanks!)

https://c-ares.org/

I have created a PoC patch.

https://github.com/mame/ruby/commit/547806146993bbc25984011d423dcc0f913b211c

By applying this patch, we can interrupt `Addrinfo.getaddrinfo` by Ctrl+C.

```
# cat /etc/resolv.conf
nameserver 72.66.115.13

# ./local/bin/ruby -rsocket -e 'Addrinfo.getaddrinfo("www.ruby-lang.org", 80)'
^C-e:1:in `getaddrinfo': Interrupt
        from -e:1:in `<main>'
```

## Discussion

### About c-ares

According to the site of c-ares, some major tools including libcurl, Wireshark, and Apache Arrow are already using c-ares. In the language interpreter, node.js seems to be using c-ares.

I am honestly not sure about the compatibility of c-ares with `getaddrinfo(3)`. I guess there is no major incompatibility because I have not experienced any name resolution problem of curl. @akr (who is the author and maintainer of Ruby's socket library) suggested to check if OS-specific name resolution, e.g., WINS on Windows, NIS on Solaris, etc., is supported. He also said that it may be acceptable even if they are not supported.

Whether to bundle c-ares source code with ruby would require further discussion. If this proposal is accepted, then c-ares will become a de facto essential dependency for practical use, like gmp, in my opinion. Incidentally, node.js bundles c-ares: https://github.com/nodejs/node/tree/main/deps/cares

### Alternative approaches

Recent glibc provides `getaddrinfo_a(3)` which performs asynchronous name resolution. However, this function has a fatal problem of being incompatible with `fork(2)`, which is heavily used in the Ruby ecosystem. In fact, the attempt to use `getaddrinfo_a(3)` (#17134) has been revert because it fails rails tests. (#17220)

Another alternative is to have a worker pthread inside Ruby that calls getaddrinfo(3). Instead of calling getaddrinfo(3) directly, `Addrinfo.getaddrinfo` would ask the worker to resolve a name and wait for a response. This method should be able to implement cancellation. (Simply put, this means reimplementation of getaddrinfo_a(3) on our own, taking into account of `fork(2).)

This has the advantages: not adding dependencies on external libraries and not having compatibility issues with `getaddrinfo(3)`. However, it is considerably more difficult to implement and maintain. An internal pthread may have a non-trivial impact on the execution efficiency and memory usage. Also, we may need to implement a mechanism to dynamically change the number of workers depending on the load.

It would be ideal if we could try and evaluate both approaches. But my current impression is that using c-ares is the quickest and best compromise.

## Contribution wanted

I have made it up to the PoC, but don't have much time to complete this. @naruse suggested me to create a ticket asking for contributions. Is anyone interested in this?

* This patch changes `rsock_getaddrinfo` to accept a timeout argument. There are several places where Qnil is passed as a timeout (where I add `// TODO` in the PoC). We need to consider what timeout we should pass.
* This cares only `getaddrinfo`, but we also need to care `getnameinfo` (and something else if any). There may be some issues I'm not aware of.
* I have not yet tested this PoC seriously. It would be great if we could evaluate it with some real apps.

Also, it would be great to hear from someone who knows more about c-ares.



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

In This Thread