-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Timeout support #29
Comments
Implement
|
Integrate timeout support for async_rt crateTo support timeout fully in async_rt crate, we need:
Users use Time Expression
Time AcquisitionWe already have
|
The timeout design looks good. I didn't dive into the Hierarchical Timing Wheels scheme. But having a design backed by a paper looks promising to me. And I am hoping that there is already a Rust implementation for the algorithm. If not, I think we can implement a simplified, good enough version for now and leave the complete implementation in the future. Could you break down the design into actionable tasks? |
actionable tasks
|
Motivation
It is common to have event waiting logics bounded with timeouts. But currently, all NGO code will wait forever if no interesting events arrive. And since there are so many system calls that may wait with timeout, we need to figure out a general mechanism to support timeout.
Background
Currently, all event wait/wakeup code in NGO eventually relies on
Waiter
/WaiterQueue
provided by theasync-rt
crate. And a convenient macro namedwaiter_loop
is provided to make it even easier for the most common pattern when usingWaiter
/WaiterQueue
, which is to 1) try to make progress with a task, 2) if not ready, wait for notifications before trying again.Here are some examples.
Exit/Wait4
The exit and wait4 system calls use
Waiter
andWaiterQueue
.Sigtimedwait
The sigtimedwait also uses
Waiter
andWaiterQueue
to wait for signals.Futex
Futexes are also backed by
Waiter
andWaiterQueue
.I/O notifications
I/O notifications, due to its importance and ubiquitousness, are implemented with three new abstractions:
Poller
,Pollee
, andEvents
.Here is a simplified code from
StreamSocket
.But behind the scense,
Poller
andPollee
are also implemented withWaiter
andWaiterQueue
.Proposed solution
The new interface
From the examples above, we can see that to support timeouts, all we have to do is to add the support of timeout to the
Waiter::wait
andPoller::wait
methods. And since the latter one is based onWaiter
, the problem is now boiled down to support timeout for theWaiter::wait
method.Since the
waiter_loop
macro does not take an argument of timeout, we can either extend the macro with an extra argument or create a new macro namedwaiter_loop_with_timeout
(any better name?). Either way, thetimeout
-supporting version macro should return aResult<()>
for the loop, thus the user can capture and handle errors due to timeout.The refined interface
It is quite common to invoke
Waiter::wait
in a loop. But due to Rust's ownership and move semantics, the following code is not valid.An error of "use of moved value" will be reported by the Rust compiler.
To workaround this problem, one solution is to redefine the signature of the
wait
method.This way, the
wait
method can accept bothOption<&mut Duration>
andOption<&mut &mut Duration>
as its argument. Thus, we can rewrite the loop as the following.Changes to the
wait
methodNow let's try to figure out the implementationn of the
wait
method. Assume that we have a decorator futureTimeout
that can wrap any future to make a new future that completes until the internal future completes or the timeout expires.With this new convenient primitive of
Timeout
, we can now rewrite theWaiter::wait
method as the following.Make
WaitFuture
cancel-safeCancelling Rust futures is still an open problem. Simply dropping a future before its completion may even introduce memory safety issues. Currently, there is no good-enough, language-level solution. See this article for more info.
Luckily, in this proposal, we only need to cancel a very specific future---
WaitFuture
. The original version ofWaitFuture
is written on the assumption that the future always run to completion.Simply droping a
WaitFuture
may result in aWaiter
/WaiterInner
in an unexpected state. To fixe this issue, we can implement aDrop
trait forWaitFuture
to ensure thatWaiter
/WaiterInner
's state is good even whenWaitFuture
is cancelled.Implement
Timeout<F: Future>
Needs to be added :)
The text was updated successfully, but these errors were encountered: