withoutboats / romio

asynchronous networking primitives

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tracking issue: timer bindings

yoshuawuyts opened this issue · comments

commented

From talking with @withoutboats: it would make sense to create a timer implementation on top of OS timers. I'm not quite sure yet how this should work, but a cursory search shows that there's multiple options available on unix through timer_create(2) and epoll(2) with a timeout parameter. I'm not sure yet about Windows.

References

commented

@luover how about *nix and examples?

@kpp I find it has some linux support now

commented

@luover oh wow, that looks great. Very clean. Thanks for sharing!

@tinaun's crate looks great to me. :) It makes me wonder about what the boundary is for abstracting over different timer sources.

tokio-timer provides two futures and two streams: delay, interval, timeout, and delayqueue. futures-native-timers provides only the first two. Timeout can be fairly trivially implemented by combining select and delay, and i suspect delayqueue is similarly possible to construct by combining concurrency primitives with delay. I wonder, also, about interval: at the levels of precision we care about, could it it not be written by triggering a delay repeatedly?

In other words, it seems like the "abstraction boundary" between timers and the rest of the ecosystem could just be Delay - an async fn(Instant) or async fn(Duration).

I believe the approach that should be adopted to timers is to provide generic Timer interface that each runtime could implement as in most cases OS dependent timer facilities can be diverse, and only few APIs actually require polling (such as fd timers on linux)

Therefore I started working on generic facilities for async https://github.com/DoumanAsh/async-timer

For now it has Timer trait, few platform dependent implementations (windows thread pool, posix based, mac os dispatch source and wasm based on web APIs)
In addition to that it has Delay and Timed primitives. I didn't include anything else for now as it is dependency on futures for now and can be implemented on top of Delay

i don't really feel like a timer implementation is the right place for trait based generics. individual future runtimes could have ways of choosing from several different timers, but i don't feel like a top level trait is a good fit for them

@tinaun How end-user future that depends on timer is going to choose timer implementation?
Without some sorta generic interface, you cannot really swap implementations

Or do you mean at compile time? It is not flexible, the whole point of customization through underlying Timer is to allow user to change implementation of Timer when it is required.
While Posix timers are available on most unix platforms, some, e.g. Linux, provides you with alternative implementation that may or may not be more performant.
How user is going to customize it?
If you believe such cases doesn't matter, then say so.
There is no way to allow customization without generics

the generic trait for abstracting over different timer sources already exists, its called Future!

Future can represent only one shot timer.

But well for sub-set of problems it can be used too I guess

"I wonder, also, about interval: at the levels of precision we care about, could it it not be written by triggering a delay repeatedly."
That's inciteful, on a use case basis certainly better than spinning. It is something you MUST know during design. A sort of minimum no of time chunks your larger functions have as a property.
Based on a range related to time slice and instruction execution time as you would know.

This all exists harmoniously from core to crate to design patterns fir apps. It's mlti-leveled of course. A link and a question link:

Quote:
The following timer management design patterns are used very frequently in Real-time systems:

Recovering from Message Loss
Recovering from Software Faults
Sequencing Operations
Polling
Periodic Operations
Failure Detection
Collecting Messages
Inactivity Detection

End quote.
https://www.eventhelix.com/RealtimeMantra/Patterns/TimerManagementDesignPatterns.htm

You must meet all these requirements in a Rusty perfromant manner.

I support your suggestion as a Trait but wonder about dirty memory reads that reflect a false state:
https://users.rust-lang.org/t/dirty-memory-reads-and-mpmc-multiple-producer-consumer/31410/2

I don't see any issues here or with Rust.