include Tenacious_lib.Tenacious_intf.Sval init : concurrency:int ‑> unitTo be called to set the amount of concurrency allowed before any call to exec.
module Heart : Tenacious_lib.Heart_intf.Sinclude Core.Monad.Sinclude Base__.Monad_intf.S_without_syntax with type a t := a tinclude Base__.Monad_intf.Infix with type a t := a tmodule Monad_infix : Base__.Monad_intf.Infix with type a t := a tval exec : 'a t ‑> name:Core.String.t Core.Lazy.t ‑> ('a * Heart.t) Async.Deferred.tnote that exec adds a new root in the observable tenacious graph,
even if you call it from a function given to embed or lift.
val embed : (cancel:Heart.t ‑> ('a * Heart.t) option Async.Deferred.t) ‑> 'a tval memoize : name:Core.String.t Core.Lazy.t ‑> 'a t ‑> 'a tval bracket : 'a t ‑> running:(int ‑> unit) ‑> finished:('a ‑> unit) ‑> cancelled:(unit ‑> unit) ‑> 'a tThis is most useful in combination with memoize:
memoize (bracket ~running ~finished ~cancelled x).
Without memoize, you can get multiple concurrent running..canceled and
running..finished blocks even when your tenacious doesn't breaks its heart.
val lift : (unit ‑> ('a * Heart.t) Async.Deferred.t) ‑> 'a tlift is specialization/simplification of embed
cutoff is dangerous:
it will delay heart breakage for the time it takes to re-compute the value so
evaluating a memoize (cutoff x) might give you stale values even when memoize x
wouldn't.
We have had a solution in the form of val protecting_cutoffs : 'a t -> 'a t
that would only return a value after waiting for all cutoffs to finish.
We removed the function right after f322aafe57c1 because it was unused
and was preventing an optimization for Heart.or_broken.
race non-deterministically chooses the first computation to succeed,
cancels the other.
Note that as it's non-deterministic it should be used with care. Ideally the final result should not depend on which result gets produced first.
module Result : sig ... endnon-deterministically choose the faster one to fail.
if neither fails, returns both.
The race caveats apply.
A mutable variable whose state can be watched as a Tenacious computation.
'a Var.t is conceptually a 'a Ref.t with
Var.{create,get,set,replace} corresponding to
Ref.{create,(!),(:=),replace}.
The important difference is the watch function, that lets you construct tenacious
computations that depend on the value of the variable.