Skip to content

Commit fd5ef0e

Browse files
committed
Forward arguments Task#wait -> Promise#wait including timeout:.
1 parent c5892ad commit fd5ef0e

2 files changed

Lines changed: 43 additions & 2 deletions

File tree

lib/async/task.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,15 @@ def async(*arguments, **options, &block)
264264
#
265265
# Conceptually speaking, waiting on a task should return a result, and if it throws an exception, this is certainly an exceptional case that should represent a failure in your program, not an expected outcome. In other words, you should not design your programs to expect exceptions from `#wait` as a normal flow control, and prefer to catch known exceptions within the task itself and return a result that captures the intention of the failure, e.g. a `TimeoutError` might simply return `nil` or `false` to indicate that the operation did not generate a valid result (as a timeout was an expected outcome of the internal operation in this case).
266266
#
267+
# @parameter timeout [Numeric] The maximum number of seconds to wait for the result before raising a `TimeoutError`, if specified.
267268
# @raises [RuntimeError] If the task's fiber is the current fiber.
268269
# @returns [Object] The final expression/result of the task's block.
269270
# @asynchronous This method is thread-safe.
270-
def wait
271+
def wait(...)
271272
raise "Cannot wait on own fiber!" if Fiber.current.equal?(@fiber)
272273

273274
# Wait for the task to complete:
274-
@promise.wait
275+
@promise.wait(...)
275276
end
276277

277278
# For compatibility with `Thread#join` and similar interfaces.

test/async/task.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,46 @@ def sleep_forever
868868
expect(task.wait).to be == error
869869
expect(task.result).to be == error
870870
end
871+
872+
it "raises TimeoutError if timeout expires before task completes" do
873+
reactor.run do
874+
slow_task = reactor.async do
875+
sleep(10)
876+
:done
877+
end
878+
879+
expect do
880+
slow_task.wait(timeout: 0.001)
881+
end.to raise_exception(Async::TimeoutError)
882+
883+
slow_task.cancel
884+
end
885+
end
886+
887+
it "returns the result if the task completes within the timeout" do
888+
reactor.run do
889+
fast_task = reactor.async do
890+
:done
891+
end
892+
893+
expect(fast_task.wait(timeout: 10)).to be == :done
894+
end
895+
end
896+
897+
it "raises TimeoutError immediately if timeout is zero and task is not complete" do
898+
reactor.run do
899+
slow_task = reactor.async do
900+
sleep(10)
901+
:done
902+
end
903+
904+
expect do
905+
slow_task.wait(timeout: 0)
906+
end.to raise_exception(Async::TimeoutError)
907+
908+
slow_task.cancel
909+
end
910+
end
871911
end
872912

873913
with "#wait_all" do

0 commit comments

Comments
 (0)