Feature #17470
closedIntroduce non-blocking `Timeout.timeout`
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.
Updated by Eregon (Benoit Daloze) almost 4 years ago
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 4 years ago
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 4 years ago
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 4 years ago
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 4 years ago
- Related to Feature #17363: Timeouts added
Updated by jeremyevans0 (Jeremy Evans) over 3 years ago
- Tracker changed from Bug to Feature
- Backport deleted (
2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)
Updated by ioquatix (Samuel Williams) over 3 years ago
@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 3 years ago
@jsc (Justin Collins) 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 3 years ago
- Status changed from Open to Closed
- Assignee set to ioquatix (Samuel Williams)
Implemented in https://github.com/ruby/ruby/pull/4173.