Skip to content

Instant::until, calculating the time until another Instant  #55

Closed as not planned
@dvdsk

Description

@dvdsk

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 Instants 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 its Instant 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions