Description
This proposes a minor API addition improving readability a tiny bit. I follow the wording in the template therefore I speak about a problem
. Not having this API is not a problem in my opinion however I think this change would (slightly) improve the standard library. For me such a small change seems like a good way to start contributing to Rust.
Proposal
Problem statement
There is no (very) easy/readable way to calculate the time until an Instant
. Instead, we use: deadline.saturating_duration_since(Instant::now())
where deadline is a Instant
possibly in the future. Using deadline.duration_since(Instant::now())
by mistake will lead to a panic when the deadline
lies in the past, this is an easy mistake to make.
The readability problem can be mitigated by assigning the result to a variable named until
. This however comes at the cost of making code longer.
Motivation, use-cases
The time until some Instant
is often used to pause the current thread until that Instant
has elapsed:
let until = hb_deadline
.saturating_duration_since(Instant::now())
.as_millis();
thread::sleep(until);
I use calculating the time till an Instant
to track performance:
match timeout_at(hb_deadline, heartbeat.notified()).await {
Err(_) => {
warn!("heartbeat for term {} timed out", data.term());
return;
}
Ok(_) => {
let until = hb_deadline
.saturating_duration_since(Instant::now())
.as_millis();
if until < Duration::from_millis(50) {
warn!("overloaded");
// ensure we no longer accept new requests
}
)
}
Most other use-cases will take the shape of a planning problem, checking if there is enough time left to perform an action before a deadline.
Solution sketches
A solution would be to add an until method to Instant
. This would complement the existing elapsed method. Its API would be:
Instant::until(&self) -> Duration
Similarly to elapsed
the until
method would be a wrapper around one line containing only existing Instant
methods. Specifically it will call argument.saturating_duration_since(Instant::now())
.
There are widely used libraries that mirror the Instant
type of the std (time
and tokio
). They currently implement all std Instant
methods. To keep their Instant
s similar they will need to adopt Instant::until
.
An alternative could be modifying and adding to the documentation of saturating_duration_since
to highlight how to solve the use cases above.
The second solution has as advantage that there is no API change. I however prefer adding a function as that also solves the readability 'problem' and is more discoverable.
Links and related work
- The go-lang time package has an
Until
function that mirrors the proposed API change. - Java's time package has an
until
member for itsInstant
class. - Python and C++ do not have a function for this
The languages in this list with an Instant
type to offer an until method.
The tokio framework has a sleep_until
function that solves the sleep use case.
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.
if the libs-api team decides to adopt this proposal I would like to do the implementation to learn a bit more about contributing to rust