-
Notifications
You must be signed in to change notification settings - Fork 284
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This module can be used to know when a certain amount has passed since the timer startted. Useful for encoding timeouts, schedule actions periodically and similar. Signed-off-by: Pau Ruiz Safont <[email protected]>
- Loading branch information
Showing
6 changed files
with
118 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ depends: [ | |
"ocaml" {>= "4.12"} | ||
"alcotest" {with-test} | ||
"astring" | ||
"mtime" | ||
"ptime" | ||
"odoc" {with-doc} | ||
] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
(ocaml (>= 4.12)) | ||
(alcotest :with-test) | ||
astring | ||
mtime | ||
ptime | ||
) | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
type t = {start: Ptime.t; elapsed: Mtime_clock.counter; timeout: Mtime.Span.t} | ||
|
||
type remaining = Spare of Mtime.Span.t | Excess of Mtime.Span.t | ||
|
||
let is_shorter a ~than:b = Mtime.Span.compare a b < 0 | ||
|
||
let is_longer a ~than:b = Mtime.Span.compare a b > 0 | ||
|
||
let start ~timeout = | ||
{start= Ptime_clock.now (); elapsed= Mtime_clock.counter (); timeout} | ||
|
||
let timeout {timeout; _} = timeout | ||
|
||
let elapsed t = Mtime_clock.count t.elapsed | ||
|
||
let remaining t = | ||
let elapsed = Mtime_clock.count t.elapsed in | ||
let difference = Mtime.Span.abs_diff t.timeout elapsed in | ||
if Mtime.Span.compare t.timeout elapsed > 0 then | ||
Spare difference | ||
else | ||
Excess difference | ||
|
||
let expired t = match remaining t with Spare _ -> false | Excess _ -> true | ||
|
||
let deadline_of t = | ||
Mtime.Span.to_uint64_ns t.timeout | ||
|> Int64.to_float | ||
|> Ptime.Span.of_float_s | ||
|> Option.get | ||
|> Ptime.(Span.add Ptime.(to_span t.start)) | ||
|> Ptime.Span.to_float_s | ||
|
||
let shorten_by dur t = | ||
let timeout = | ||
if is_longer dur ~than:t.timeout then | ||
Mtime.Span.zero | ||
else | ||
Mtime.Span.abs_diff dur t.timeout | ||
in | ||
{t with timeout} | ||
|
||
let extend_by dur t = | ||
let timeout = Mtime.Span.add dur t.timeout in | ||
{t with timeout} | ||
|
||
(* Conversion functions *) | ||
let span_to_s span = | ||
Mtime.Span.to_uint64_ns span |> Int64.to_float |> fun ns -> ns /. 1e9 | ||
|
||
let s_to_span s = | ||
let micros_of = Float.to_int (s *. 1_000_000.) in | ||
Mtime.Span.(micros_of * us) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
(** This module is useful for knowing that a set amount of time has passed | ||
since a particular moment in time. For example, to know when pasta is | ||
cooked al dente. *) | ||
type t | ||
|
||
type remaining = Spare of Mtime.Span.t | Excess of Mtime.Span.t | ||
|
||
val start : timeout:Mtime.Span.t -> t | ||
(** [start ~timeout] starts a timer that expires after [timeout] has passed. | ||
The wait is done in monotonic time, not in POSIX time. *) | ||
|
||
val timeout : t -> Mtime.Span.t | ||
(** [timeout timer] returns the amount of time after which the timer expires, | ||
from the moment it was started. *) | ||
|
||
val expired : t -> bool | ||
(** [expired timer] returns whether [timer] has reached the timeout it was | ||
set to. *) | ||
|
||
val elapsed : t -> Mtime.Span.t | ||
(** [elapsed timer] returns the amount of time elapsed since [timer] was | ||
started. *) | ||
|
||
val remaining : t -> remaining | ||
(** [remaining timer] returns the amount of spare time is left until it | ||
expires, or the amount of excess time since it expired. *) | ||
|
||
val deadline_of : t -> float | ||
(** [deadline_of timer] returns the posix timestamp when the timer expires. | ||
This is an approximation as the timer doesn't take leap seconds into | ||
account when waiting. The use of this function is discouraged and it's | ||
only provided for backwards-compatible reasons. *) | ||
|
||
val shorten_by : Mtime.Span.t -> t -> t | ||
(** [shorten_by amount timer] creates a new timer with the timeout of [timer] | ||
shortened by [amount]. The starting time doesn't change. *) | ||
|
||
val extend_by : Mtime.Span.t -> t -> t | ||
(** [extend_by amount timer] creates a new timer with the timeout of [timer] | ||
delayed by [amount]. The starting time doesn't change. *) | ||
|
||
(** Mtime.Span helpers *) | ||
|
||
val is_shorter : Mtime.Span.t -> than:Mtime.Span.t -> bool | ||
(** [is_shorter dur ~than] returns whether [dur] lasts less than [than]. *) | ||
|
||
val is_longer : Mtime.Span.t -> than:Mtime.Span.t -> bool | ||
(** [is_longer dur ~than] returns whether [dur] lasts more than [than]. *) | ||
|
||
val span_to_s : Mtime.Span.t -> float | ||
(** [span_to_s span] converts a time span into seconds, represented by a float. | ||
When the span is longer than ~54 years it becomes unprecise, avoid whenever | ||
possible, this is unavoidable when using Thread.wait functions and related. | ||
*) | ||
|
||
val s_to_span : float -> Mtime.Span.t | ||
(** [s_to_span] convert a float representing seconds to a timespan, retains | ||
microsecond precision. Avoid whenever possible, some RPC function already | ||
use this so it needs to be available. *) |