A synchronous version of
advance_by_alarms runs alarms immediately, rather than enqueueing Async jobs.
Synchronous_time_source is a wrapper around
Timing_wheel. One difference is that
Synchronous_time_source alarms fire in non-decreasing time order, whereas in
Timing_wheel that is only true for alarms in different time intervals as determined by
module T1 : sig ... end
module Read_write : sig ... end
module Id : Core.Unique_id.Id
val sexp_of_t : t -> Sexplib0.Sexp.t
val invariant_with_jobs : job: (Async_kernel__.Types.Execution_context.t, Obj.t -> unit, Obj.t) Tuple_pool.Slots.t3 Tuple_pool.Pointer.t Core.Invariant.t -> t Core.Invariant.t
include Core.Invariant.S with type t := t
val invariant : t -> unit
id t returns a unique, consistent identifier which can be used e.g. as a map or hash table key.
val create : ?timing_wheel_config:Timing_wheel.Config.t -> now:Core.Time_ns.t -> unit -> Core.read_write T1.t
create ~now () creates a new time source. The default
timing_wheel_config has 100 microsecond precision, with levels of >1s, >1m, >1h, >1d. The
timing_wheel_config is used to tune performance; configuration does not affect the fact that alarms fire in non-decreasing time order.
val alarm_precision : [> Core.read ] T1.t -> Core.Core_private.Time_ns_alternate_sexp.Span.t
is_wall_clock reports whether this time source represents 'wall clock' time, or some alternate source of time.
val now : [> Core.read ] T1.t -> Core.Time_ns.t
The behavior of
now is special for
wall_clock (); it always calls
(), so it can return times that the time source has not yet been advanced to.
val timing_wheel_now : [> Core.read ] T1.t -> Core.Time_ns.t
Removes the special behavior of
wall_clock (); it always returns the timing wheel's notion of now, which means that the following inequality always holds:
timing_wheel_now () <= now ().
val run_at : [> Core.read ] T1.t -> Core.Time_ns.t -> callback -> unit
run_at t at f schedules an alarm that will run
f during the next subsequent
advance_by_alarms t ~to_ that causes
now t >= at. If
at <= now t, then
f will to run at the next call to
f is allowed to do all
Synchronous_time_source operations except for
f is already running during
advance_by_alarms. Adding alarms is not zero-alloc and the underlying events live in the OCaml heap.
val run_after : [> Core.read ] T1.t -> Core.Core_private.Time_ns_alternate_sexp.Span.t -> callback -> unit
run_after t span f is
run_at t (now t + span) f.
val run_at_intervals : [> Core.read ] T1.t -> Core.Core_private.Time_ns_alternate_sexp.Span.t -> callback -> unit
run_at_intervals t span f schedules
f to run at intervals
now t + k * span, for k = 0, 1, 2, etc.
run_at_intervals raises if
span < alarm_precision t.
val max_allowed_alarm_time : [> Core.read ] T1.t -> Core.Time_ns.t
max_allowed_alarm_time t returns the greatest
at that can be supplied to
max_allowed_alarm_time is not constant; its value increases as
now t increases.
val duration_of : [> Core.read ] T1.t -> (unit -> 'a) -> 'a * Core.Core_private.Time_ns_alternate_sexp.Span.t
duration_of t f invokes
f and measures how long it takes for the call to finish.
module Event : sig ... end
val default_timing_wheel_config : Timing_wheel.Config.t
val wall_clock : unit -> t
A time source with
now t given by wall-clock time (i.e.
Time_ns.now), and automatically advanced at the start of each Async cycle. The wall clock uses the same timing wheel as that used by the Async scheduler, and is hence similarly affected by the
ASYNC_CONFIG environment variable.
For Scheduler Implementors
val length : [> Core.write ] T1.t -> int
length t returns the number of alarms in the underlying
val next_alarm_runs_at : [> Core.write ] T1.t -> Core.Time_ns.t option
next_alarm_runs_at t returns a time to which the clock can be advanced such that an alarm will fire, or
t has no alarms that can ever fire.
Note that this is not necessarily the minimum such time, but it's within
alarm_precision of that.
If an alarm was already fired (e.g. because it was scheduled in the past), but its callbacks were not run yet, this function returns
Some now, to indicate that a trivial time advancement is sufficient for those to run.
val next_alarm_fires_at : [> Core.write ] T1.t -> Core.Time_ns.t option
- deprecated [since 2021-06] Use [next_alarm_runs_at]
val advance_by_alarms : [> Core.write ] T1.t -> to_:Core.Time_ns.t -> unit Core.Or_error.t
advance_by_alarms t ~to_ advances
t's time to
to_, running callbacks for all alarms in
at <= to_. Callbacks run in nondecreasing order of
to_ <= now t, then
now t does not change (and in particular does not go backward), but alarms with
at <= to_ may still may fire.
val advance_by_max_alarms_in_each_timing_wheel_interval : [> Core.write ] T1.t -> to_:Core.Time_ns.t -> unit Core.Or_error.t
A version of
advance_by_alarms with some weird behavior caused by timing wheel
alarm_precision: if there are multiple alarms within the same timing_wheel precision bucket, then this function fires them all at the same time (when the last of the bunch of alarms is supposed to fire). The time
to_ counts as an alarm for this purpose. (any alarms in the same bucket as
to_ will be fired at time
advance_by_alarms has no such weirdness, and fires every alarm at the time that alarm is scheduled.
val advance_directly : [> Core.write ] T1.t -> to_:Core.Time_ns.t -> unit Core.Or_error.t
advance_directly, you probably should use
advance_directly t ~to_ advances the clock directly to
advance_by_alarms advances the clock in steps, to each intervening alarm. In particular periodic/rearming timers will fire at most twice.
val max_alarm_time_in_min_timing_wheel_interval : [> Core.write ] T1.t -> Core.Time_ns.t option
This value is close to
next_alarm_fires_at but differs from it by at most
alarm_precision. Requires a more expensive iteration of alarms.
This is a closer approximation of the minimum time at which an alarm will fire, but it's still not there (you need min_alarm_time_... for that).
val has_events_to_run : [> Core.write ] T1.t -> bool
Returns true iff there is work to do without advancing time further. (This can be caused by scheduling events in the past, or starting a recurring event.)