Project

General

Profile

Actions

Feature #17470

closed

Introduce non-blocking `Timeout.timeout`

Feature #17470: Introduce non-blocking `Timeout.timeout`

Added by ioquatix (Samuel Williams) almost 5 years ago. Updated over 4 years ago.

Status:
Closed
Target version:
-
[ruby-core:101704]

Description

In this bug report, user complained that Timeout.timeout does not work correctly with scheduler: https://github.com/socketry/async-io/issues/43

We should introduce non-blocking timeout.

I propose the following:

rb_fiber_scheduler_with_timeout(VALUE scheduler, VALUE timeout, VALUE block) 

We can directly modify Timeout.timeout to invoke this hook.


Related issues 1 (1 open0 closed)

Updated by Eregon (Benoit Daloze) almost 5 years ago Actions #1 [ruby-core:101712]

How would that work, what would be a sample implementation of the hook?
Timeout.timeout must be able to interrupt non-IO operations as well.

Updated by ioquatix (Samuel Williams) almost 5 years ago Actions #2 [ruby-core:101721]

Timeout.timeout must be able to interrupt non-IO operations as well.

Actually, that's not necessarily true, even for the current implementation, see getaddrinfo for example.

Updated by jsc (Justin Collins) almost 5 years ago Actions #3 [ruby-core:101730]

It appears that Timeout.timeout does not work when a Fiber scheduler is set, regardless of the implementation, even when Fibers are not explicitly in use.

Simple example using the sample scheduler:

require 'timeout' require 'fiber' require_relative 'scheduler' scheduler = Scheduler.new Fiber.set_scheduler scheduler Timeout.timeout 1 do puts "hello" end 

This code will print "hello" then hang.

Updated by Eregon (Benoit Daloze) almost 5 years ago Actions #4 [ruby-core:101750]

ioquatix (Samuel Williams) wrote in #note-2:

Actually, that's not necessarily true, even for the current implementation, see getaddrinfo for example.

You're completely evading my question :p
Could you answer it please?

That's one of the very rare cases, maybe even the only case in core methods that cannot be interrupted by Thread#raise.

Is the idea to simply give up on interrupting anything that's not handled by the scheduler if there is a Fiber.scheduler, or something better?
That seems too incompatible to me.
I think a new API to interrupt only scheduler things might make more sense (related to #17363).

Updated by Eregon (Benoit Daloze) almost 5 years ago Actions #5

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago Actions #6

  • Tracker changed from Bug to Feature
  • Backport deleted (2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)

Updated by ioquatix (Samuel Williams) over 4 years ago Actions #7 [ruby-core:102464]

@Eregon (Benoit Daloze) without preemptive scheduling it won't be possible. There are other cases where the GVL is not released, e.g. the sqlite3 gem. In the case of the scheduler, Timeout.timeout is completely broken, so this is an improvement any way you cut it.

Updated by ioquatix (Samuel Williams) over 4 years ago Actions #8 [ruby-core:102466]

@jsc I tried your example but it seems to work fine?

 MESSAGE = "Hello World" def test_timeout_on_main_fiber message = nil thread = Thread.new do scheduler = Scheduler.new Fiber.set_scheduler scheduler Timeout.timeout(1) do message = MESSAGE end end thread.join assert_equal MESSAGE, message end 

Updated by ioquatix (Samuel Williams) over 4 years ago Actions #9 [ruby-core:103091]

  • Status changed from Open to Closed
  • Assignee set to ioquatix (Samuel Williams)
Actions

Also available in: PDF Atom