Module omaha_client::time

source ·
Expand description

The omaha_client::time module provides a set of types and traits to allow for the expressing of time using both a wall-time clock, and a monotonic clock.

The motivation for this is that wall-time is subject to being artibtrarily moved (forwards or backwards as the system’s timekeeper decides is necessary), to keep it in sync with external systems.

The monotonic clock, on the other hand, provides a consistently moving forward notion of time, but one that is not anchored at any particular external point in time. It’s epoch is therefore somewhat opaque by nature. Rust’s std::time::Instant takes this to the extreme of making the underlying value completely hidden from callers.

One aspect of the TimeSource trait and the ComplexTime type is that they provide a way to pair the two timelines, and construct a time that is given in terms of each of these dimensions.

What it doesn’t try to do, is so that these pairings are the same time. They can be observations made concurrently (as in the case of TimeSource::now() -> ComplexTime), or they can be bounds for when an event in the future can happen:

use omaha_client::time::{ComplexTime, MockTimeSource, TimeSource, Timer};
use omaha_client::time::timers::MockTimer;
use std::time::{Duration, SystemTime};
let past_event_wall_time: SystemTime = SystemTime::now();
let source = MockTimeSource::new_from_now();
let duration_to_next = Duration::from_secs(1*60*60); // one hour
let rough_next_event_time = ComplexTime{
                              wall: past_event_wall_time + duration_to_next,
                              mono: source.now_in_monotonic() + duration_to_next
let mut timer = MockTimer::new();

The above setups up a ComplexTime as a bound that based on an expected wall time, and monotonic time relative to now, such that the event can be described as “at time X, or within an hour” when used with Timer::wait_until, or “after time X, at least an hour from now”, if used with Timer::wait_until_all.

§Usage Guidelines

The ComplexTime and PartialComplexTime structs give the ability to represent a number of states of knowledge about a time.

When modeling the known time for something:

  • ComplexTime - When both wall and monotonic times are always known
  • PartialComplexTime - When some time (wall, monotonic, or both) is always known
  • `Option - When time is either known for both timelines, or not at all.
  • `Option - Situations where time can be in any of 4 states:
    • None whatsoever
    • Only wall time
    • Only monotonic time
    • Both are known

When modeling the time required (e.g. timer waits):

  • ComplexTime - When both wall and monotonic times are always required
  • PartialComplexTime - When some time (wall, monotonic, or both) is always required, but any or both will suffice.




  • This is a complete ComplexTime, which has values on both the wall clock timeline and the monotonic clock timeline.
  • Helper struct for providing a consistent, readable SystemTime.


  • PartialComplexTime provides a std::interator::EitherOrBoth-like type which is specifically for holding either one, or both, of the time types that make up a ComplexTime. It’s a type that holds a value for at least one of the timelines.


  • TimeSource is a trait for providing access to both the “System” (aka “Wall”) time for platform, as well as its monotonic time.
  • Trait for timers that understand how to work with the ComplexTime and PartialComplexTime types.