[#121498] [Ruby Bug#21210] IO::Buffer gets invalidated on GC compaction — "hanazuki (Kasumi Hanazuki) via ruby-core" <ruby-core@...>

Issue #21210 has been reported by hanazuki (Kasumi Hanazuki).

10 messages 2025/04/01

[#121519] [Ruby Bug#21214] VmRSS consumption increase in Ruby 3.4.2 vs Ruby 3.3.6 — "mood_vuadensl (LOIC VUADENS) via ruby-core" <ruby-core@...>

Issue #21214 has been reported by mood_vuadensl (LOIC VUADENS).

9 messages 2025/04/02

[#121542] [Ruby Bug#21217] Integer.sqrt produces wrong results even on input <= 1e18 — "hjroh0315 (Matthew Roh) via ruby-core" <ruby-core@...>

Issue #21217 has been reported by hjroh0315 (Matthew Roh).

8 messages 2025/04/06

[#121551] [Ruby Feature#21219] `Object#inspect` accept a list of instance variables to display — "byroot (Jean Boussier) via ruby-core" <ruby-core@...>

Issue #21219 has been reported by byroot (Jean Boussier).

10 messages 2025/04/07

[#121556] [Ruby Bug#21220] Memory corruption in update_line_coverage() [write at index -1] — "mbcodeandsound (Mike Bourgeous) via ruby-core" <ruby-core@...>

Issue #21220 has been reported by mbcodeandsound (Mike Bourgeous).

16 messages 2025/04/07

[#121560] [Ruby Feature#21221] Proposal to upstream ZJIT — "maximecb (Maxime Chevalier-Boisvert) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMjIxIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IG1heGltZWNiIChNYXhpbWUgQ2hldmFs

8 messages 2025/04/07

[#121565] [Ruby Feature#21254] Inlining Class#new — "tenderlovemaking (Aaron Patterson) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMjU0IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHRlbmRlcmxvdmVtYWtpbmcgKEFhcm9u

12 messages 2025/04/07

[#121601] [Ruby Feature#21258] Retire CGI library from Ruby 3.5 — "hsbt (Hiroshi SHIBATA) via ruby-core" <ruby-core@...>

Issue #21258 has been reported by hsbt (Hiroshi SHIBATA).

11 messages 2025/04/09

[#121621] [Ruby Feature#21262] Proposal: `Ractor::Port` — "ko1 (Koichi Sasada) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMjYyIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGtvMSAoS29pY2hpIFNhc2FkYSkuDQoN

8 messages 2025/04/10

[#121627] [Ruby Feature#21264] Extract Date library from Ruby repo in the future — "hsbt (Hiroshi SHIBATA) via ruby-core" <ruby-core@...>

Issue #21264 has been reported by hsbt (Hiroshi SHIBATA).

8 messages 2025/04/11

[#121686] [Ruby Feature#21274] Show performance warnings for easily avoidable unnecessary implicit splat allocations — "jeremyevans0 (Jeremy Evans) via ruby-core" <ruby-core@...>

Issue #21274 has been reported by jeremyevans0 (Jeremy Evans).

6 messages 2025/04/18

[#121700] [Ruby Feature#21279] Bare "rescue" should not rescue NameError — "AMomchilov (Alexander Momchilov) via ruby-core" <ruby-core@...>

Issue #21279 has been reported by AMomchilov (Alexander Momchilov).

9 messages 2025/04/21

[#121702] [Ruby Bug#21280] StringIO#set_encoding warns when backed by chilled string literal — "jeremyevans0 (Jeremy Evans) via ruby-core" <ruby-core@...>

Issue #21280 has been reported by jeremyevans0 (Jeremy Evans).

13 messages 2025/04/22

[#121721] [Ruby Bug#21283] Some tests of TestMkmfConvertible is failing with VS2022 17.14.0 preview 4.0 — "hsbt (Hiroshi SHIBATA) via ruby-core" <ruby-core@...>

Issue #21283 has been reported by hsbt (Hiroshi SHIBATA).

8 messages 2025/04/24

[#121745] [Ruby Bug#21286] Windows - MSYS2 just updated to GCC 15.1.0, builds failing — "MSP-Greg (Greg L) via ruby-core" <ruby-core@...>

Issue #21286 has been reported by MSP-Greg (Greg L).

15 messages 2025/04/27

[#121755] [Ruby Misc#21290] Unable to build ruby extension on Fedora 42 due to possible GCC 15 issues — "lukef (Luke Freeman) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxMjkwIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGx1a2VmIChMdWtlIEZyZWVtYW4pLg0K

8 messages 2025/04/28

[ruby-core:121725] [Ruby Feature#20610] Float::INFINITY as IO.select timeout argument

From: "akr (Akira Tanaka) via ruby-core" <ruby-core@...>
Date: 2025-04-24 17:06:46 UTC
List: ruby-core #121725
Issue #20610 has been updated by akr (Akira Tanaka).

Status changed from Open to Closed

committed.
https://github.com/ruby/ruby/commit/698ef864a59004f468c77534d59e51e862ec2624

----------------------------------------
Feature #20610: Float::INFINITY as IO.select timeout argument
https://bugs.ruby-lang.org/issues/20610#change-112778

* Author: akr (Akira Tanaka)
* Status: Closed
----------------------------------------
I propose IO.select accepts Float::INFINITY as a timeout argument.
It behaves the same as nil which means IO.select will block indefinitely.

Motivation:

Currently, the Ruby convention to indicate no timeout is using nil.
This practice often forces us to treat the nil case separately.

Conceptually, no timeout can be thought of as an infinite timeout.
So I propose to accept Float::INFINITY as a timeout.

It makes us less conditionals when we need to calculate or compare timeouts.

Assume `now` method as follows to read the following examples.

```
def now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
```

Example 1: absolute timeout

Sometimes we maintain timeout as an absolute clock.

The following method takes a relative timeout as an argument.
It invokes IO.select several times and raises if the timeout is reached.

Assuming a user must specify a finite timeout, the following definition is possible.

```
# user_timeout is the required argument
def method(..., user_timeout)
  abs_timeout = now + user_timeout
  loop {
    IO.select(rs, ws, es, (abs_timeout - now).clamp(0..))
    raise "timeout" if abs_timeout < now
    ...
  }
end
```

Consider we need to make user_timeout optional.
If user_timeout is not given, no timeout occurs.
The implementation is as follows.
I think the following implementation is typical.
It needs 3 more conditionals than the above.

```
# user_timeout is an optional argument. nil means no timeout.
def method(..., user_timeout=nil)
  abs_timeout = user_timeout ? now + user_timeout : nil
  loop {
    IO.select(rs, ws, es, user_timeout ? (abs_timeout - now).clamp(0..) : nil)
    raise "timeout" if abs_timeout && (abs_timeout < now)
    ...
  }
end
```

It is possible to reduce a conditional if we use Float::INFINITY.
(`abs_timeout && (abs_timeout < now)` is changed to `abs_timeout < now`)

```
# user_timeout is an optional argument. nil means no timeout.
def method(..., user_timeout=nil)
  abs_timeout = user_timeout ? now + user_timeout : Float::INFINITY
  loop {
    IO.select(rs, ws, es, abs_timeout != Float::INFINITY ? (abs_timeout - now).clamp(0..) : nil)
    raise "timeout" if abs_timeout < now
    ...
  }
end
```

If IO.select accepts Float::INFINITY as a timeout argument (this proposal),
we can reduce one more conditional as follows.

```
# user_timeout is an optional argument. nil means no timeout.
def method(..., user_timeout=nil)
  abs_timeout = user_timeout ? now + user_timeout : Float::INFINITY
  loop {
    IO.select(rs, ws, es, (abs_timeout - now).clamp(0..))
    raise "timeout" if abs_timeout < now
    ...
  }
end
```

Example 2: minimum of timeouts

Sometimes we need to choose the minimum of several timeouts.
I think many event-driven programs use this strategy to determine the timeout for select function.

If "no timeout" is represented as nil, `[t1, t2, t3, ...].compact.min` is the minimum.

If "no timeout" is represented as Float::INFINITY, we can remove `compact`:
`[t1, t2, t3, ...].min`

However, Float::INFINITY must be converted to nil for IO.select.
This proposal removes this conversion.

Example 3: maximum of timeouts

Sometimes we need to choose the maximum of several timeouts.

We encountered this situation with a Happy Eyeballs implementation.
There are two timeouts for getaddrinfo and connect.
We need to wait the longer timeout because a timeout for one doesn't stop another.
Also, we don't ignore results after a timeout as long as the algorithm waits for something.

If "no timeout" is represented as nil, `ts = [t1, t2, t3, ...]; ts.include?(nil) ? nil : ts.max` is the maximum.

If "no timeout" is represented as Float::INFINITY, we can compute the maximum more easily: `[t1, t2, t3, ...].max`
It makes code simpler.

However, Float::INFINITY must be converted to nil for IO.select.
This proposal removes this conversion.

Several Consideration:

Consideration 1: Methods other than IO.select.

Several methods take a timeout.
An incomplete list of methods is as follows.
(I searched rb_time_interval.)

- IO.select(rs, ws, es, timeout)
- sleep(secs)
- TCPSocket.new(connect_timeout:)
- io.wait_readable(timeout)
- io.wait_writable(timeout)
- io.wait_priority(timeout)
- mutex.sleep(timeout)

Do we want to modify them consistently to accept Float::INFINITY?

Consideration 2: C-level API

If we want to change the timeout of many methods, we would wish to new C-level API similar to rb_time_interval but can return NULL.

Unfortunately, rb_time_interval cannot return NULL because the return type is struct timeval.

Note that ext/io/wait/wait.c contains get_timeout function.
It seems a good first step for such API.

Consideration 3: IEEE 754 dependency.

Minor platforms (such as VAX) use non-IEEE 754 floating point numbers without infinity.
Note that NetBSD/vax still works. (And there is an emulator, simh).

Consideration 4: It seems no major languages accept infinity as select's timeout.

I found Perl, Python, and OCaml take a floating point number as a timeout of select function.
But they don't accept infinity.


---Files--------------------------------
select-timeout-infinity.patch (1.73 KB)


-- 
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/lists/ruby-core.ml.ruby-lang.org/


In This Thread