tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
26.94k stars 2.48k forks source link

Support other time types #3918

Open rendaw opened 3 years ago

rendaw commented 3 years ago

Is your feature request related to a problem? Please describe. std::time::Instant is a black hole - it can't be converted to/from without ugly hacks which makes interop with other parts of the ecosystem painful.

Describe the solution you'd like I'd like to have a clear way to use, for instance, chrono::DateTime with sleep_until.

I'm not sure how this could be implemented. A way to get an instant from a unix timestamp could be good enough, but this would probably require Tokio's Instant to not just wrap std::time::Instant.

Or maybe removing Instant/sleep_until/DelayQueue from tokio would be better? An external implementation could rely on chrono or whatever without worrying about increasing tokio's dependencies.

Describe alternatives you've considered The only workaround I found is https://github.com/chronotope/chrono/issues/498 - convert the chrono time into a duration from now and add it to Instant::now. The issues are extra now calls, hidden dependency on the clock, and imprecision due to the clock advancing between now calls.

Darksonn commented 3 years ago

The Instant type is useful because changing the system clock doesn't affect the Instant type. Supporting unix timestamps or chrono types requires being able to detect when the system time is changed forward or backwards or just repeatedly sleeping for a short time and checking the system time again.

rendaw commented 3 years ago

I think stating limitations up front, such as not handling system time changes if something other than Instant is used, would be fine.

But I don't think it's necessary to deal with that or store any other types within the sleep struct. Probably the best solution would be to make a copy of std's Instant that's not opaque and provide methods for constructing them other than now(), and use those for converting to Instant at the time sleep is called.

Darksonn commented 3 years ago

I think it's a bad idea to have an API in Tokio that says "sleep until this unix timestamp", but which will sleep until some other time if the system clock is changed. If you want the sometimes incorrect behavior, it's very easy to go through Duration.

malaire commented 3 years ago

The issues are extra now calls, hidden dependency on the clock, and imprecision due to the clock advancing between now calls.

Extra nowcalls or imprecision of clock advancing isn't an issue: now call takes less than 1 µs while Sleep has 1 ms accuracy, so now is over 1000 times faster than needed.

As for dependency on clock, that can't be avoided when using times which are relative to clock.

malaire commented 3 years ago

... copy of std's Instant that's not opaque and provide methods for constructing them other than now() ...

What? std's Instant is also opaque

bestouff commented 3 years ago

I have a situation where I have "instants" (in fact, full dates) I fetch over the network that I have to deserialize and then I have to sleep() until this "instant", then do something else.
How would I implement that ? Namely sleep() until a given instant ?

Darksonn commented 3 years ago

@bestouff Compute the Duration from now until the desired time and sleep for that duration.