From 86d50c48caa90f302a21f85d2179df05efb74f05 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 25 Aug 2023 22:40:37 +1200 Subject: [PATCH 1/3] Better handling of internal timeout in `io_wait`. --- lib/async/scheduler.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/async/scheduler.rb b/lib/async/scheduler.rb index b4bd3d12..4efe82aa 100644 --- a/lib/async/scheduler.rb +++ b/lib/async/scheduler.rb @@ -171,17 +171,11 @@ def io_wait(io, events, timeout = nil) if timeout timer = @timers.after(timeout) do - fiber.raise(TimeoutError) + fiber.transfer end end - # Console.logger.info(self, "-> io_wait", fiber, io, events) - events = @selector.io_wait(fiber, io, events) - # Console.logger.info(self, "<- io_wait", fiber, io, events) - - return events - rescue TimeoutError - return false + return @selector.io_wait(fiber, io, events) ensure timer&.cancel end From d7a7910179917487d4e32c7e6c8daa4702370d03 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 25 Aug 2023 22:55:33 +1200 Subject: [PATCH 2/3] STDIN doesn't work in CI. --- test/async/task.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/async/task.rb b/test/async/task.rb index 4857a04e..004e3313 100644 --- a/test/async/task.rb +++ b/test/async/task.rb @@ -597,11 +597,12 @@ def after end it "will timeout while getting from stdin" do + input, output = IO.pipe error = nil reactor.async do |task| begin - task.with_timeout(0.1) {STDIN.gets} + task.with_timeout(0.1) {input.gets} rescue Async::TimeoutError => error # Ignore. end @@ -610,6 +611,9 @@ def after reactor.run expect(error).to be_a(Async::TimeoutError) + ensure + input.close + output.close end it "won't timeout if execution completes in time" do From 534b4b729b7049aebea48c7dc0e920e0318d45d9 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 25 Aug 2023 23:02:17 +1200 Subject: [PATCH 3/3] Add comments. --- test/async/task.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/async/task.rb b/test/async/task.rb index 004e3313..d1200a38 100644 --- a/test/async/task.rb +++ b/test/async/task.rb @@ -596,12 +596,13 @@ def after expect(state).to be == :timeout end - it "will timeout while getting from stdin" do + it "will timeout while getting from input" do input, output = IO.pipe error = nil reactor.async do |task| begin + # This can invoke `io_wait`, which previously had `rescue TimeoutError`, causing the timeout to be ignored. task.with_timeout(0.1) {input.gets} rescue Async::TimeoutError => error # Ignore.