Events provide variants of `run_at` and `run_after` with the ability to abort or reschedule an event that hasn't yet happened. Once an event happens or is aborted, Async doesn't use any space for tracking it.

`type ('a, 'h) t`````
`include sig ... end`
`val sexp_of_t : ('a ‑> Base.Sexp.t) ‑> ('h ‑> Base.Sexp.t) ‑> ('a, 'h) t ‑> Base.Sexp.t`
`type t_unit``= (unit, unit) t```
`include sig ... end`
`val sexp_of_t_unit : t_unit ‑> Base.Sexp.t`
`include Core_kernel.Invariant.S2 with type (a, b) t := (a, b) t`
`type ('a, 'b) t`````
`val invariant : 'a Base__.Invariant_intf.inv ‑> 'b Base__.Invariant_intf.inv ‑> ('a, 'b) t Base__.Invariant_intf.inv`
`val scheduled_at : (_, _) t ‑> Time.t`
`module Status : sig ... end`
`val status : ('a, 'h) t ‑> ('a, 'h) Status.t`

If `status` returns `Scheduled_at time`, it is possible that `time < Time.now ()` if Async's scheduler hasn't yet gotten the chance to update its clock, e.g., due to user jobs running.

`val run_at : Time.t ‑> ('z ‑> 'h) ‑> 'z ‑> (_, 'h) t`

Let `t = run_at time f z`. At `time`, this runs `f z` and transitions `status t` to `Happened h`, where `h` is result of `f z`.

More precisely, at `time`, provided `abort t a` has not previously been called, this will call `f z`, with the guarantee that `status t = Scheduled_at time`. If `f z` returns `h` and did not call `abort t a`, then `status t` becomes `Happened h`. If `f z` calls `abort t a`, then the result of `f` is ignored, and `status t` is `Aborted a`.

If `f z` raises, then `status t` does not transition and remains `Scheduled_at time`, and the exception is sent to the monitor in effect when `run_at` was called.

`val run_after : Time.Span.t ‑> ('z ‑> 'h) ‑> 'z ‑> (_, 'h) t`
`module Abort_result = Async_kernel.Time_source.Event.Abort_result`
`val abort : ('a, 'h) t ‑> 'a ‑> ('a, 'h) Abort_result.t`

`abort t` changes `status t` to `Aborted` and returns `Ok`, unless `t` previously happened or was previously aborted.

`val abort_exn : ('a, 'h) t ‑> 'a ‑> unit`

`abort_exn t a` returns `unit` if `abort t a = `Ok`, and otherwise raises.

`val abort_if_possible : ('a, _) t ‑> 'a ‑> unit`

`abort_if_possible t a = ignore (abort t a)`.

`module Fired = Async_kernel.Time_source.Event.Fired`
`val fired : ('a, 'h) t ‑> ('a, 'h) Fired.t Async_kernel__.Clock_intf.Deferred.t`
`module Reschedule_result = Async_kernel.Time_source.Event.Reschedule_result`
`val reschedule_at : ('a, 'h) t ‑> Time.t ‑> ('a, 'h) Reschedule_result.t`

`reschedule_at t` and `reschedule_after t` change the time that `t` will fire, if possible, and if not, give a reason why. Like `run_at`, if the requested time is in the past, the event will be scheduled to run immediately. If `reschedule_at t time = Ok`, then subsequently `scheduled_at t = time`.

`val reschedule_after : ('a, 'h) t ‑> Time.Span.t ‑> ('a, 'h) Reschedule_result.t`
`val at : Time.t ‑> (_, unit) t`

`at time` is `run_at time ignore ()`. `after time` is `run_after time ignore ()`.

You should generally prefer to use the `run_*` functions, which allow you to synchronously update state via a user-supplied function when the event transitions to `Happened`. That is, there is an important difference between:

              let t = run_at time f ()

and:

              let t = at time in
              fired t
              >>> function
              | Happened () -> f ()
              | Aborted () -> ()

With `run_at`, if `status t = Happened`, one knows that `f` has run. With `at` and `fired`, one does not know whether `f` has yet run; it may still be scheduled to run. Thus, with `at` and `fired`, it is easy to introduce a race. For example, consider these two code snippets:

              let t = Event.after (sec 2.) in
              upon (Event.fired t) (function
                | Aborted () -> ()
                | Happened () -> printf "Timer fired");
              upon deferred_event (fun () ->
                match Event.abort t () with
                | Ok -> printf "Event occurred"
                | Previously_aborted () -> assert false
                | Previously_happened () -> printf "Event occurred after timer fired");

              let t = Event.run_after (sec 2.) printf "Timer fired" in
              upon deferred_event (fun () ->
                match Event.abort t () with
                | Ok -> printf "Event occurred"
                | Previously_aborted () -> assert false
                | Previously_happened () -> printf "Event occurred after timer fired");

In both snippets, if `Event.abort` returns `Ok`, "Timer fired" is never printed. However, the first snippet might print "Event occurred after timer fired" and then "Timer fired". This confused ordering cannot happen with `Event.run_after`.

`val after : Time.Span.t ‑> (_, unit) t`