type ('state, 'job_tag) tEvery Key.t in the table has an associated state, which each job running on that
key gets access to. Jobs maybe have an associated job_tag which is provided
purely to assist debugging, as the tag is included in the sexp serialization of
t.
include sig ... endval sexp_of_t : ('state ‑> Base.Sexp.t) ‑> ('job_tag ‑> Base.Sexp.t) ‑> ('state, 'job_tag) t ‑> Base.Sexp.tval create : unit ‑> (_, _) tval enqueue : ('state, 'job_tag) t ‑> key:Key.t ‑> ?tag:'job_tag ‑> ('state option ‑> 'b Async.Deferred.t) ‑> 'b Async.Deferred.tenqueue t ~key f enqueues f for key. f will be called with the state of
key when invoked.
Invariant 1: it is guaranteed that f will not be called immediately.
Invariant 2: if f raises, then the exception will be raised to the monitor in
effect when enqueue was called. Subsequent jobs for key will proceed.
Invariant 3: to avoid race, there are no deferred operations between finding the
state and calling f with the state found. Otherwise, the user would need to
consider the race that the state passed to f might have been changed by
set_state.
set_state t key state_opt sets the state for key immediately. The state will be
kept internally until set to None
num_unfinished_jobs t key returns the number of jobs for key including including
pending and running.
Fold over keys with states or pending/running jobs. It's safe to mutate (enqueue
or set_state) when folding
val prior_jobs_done : (_, _) t ‑> unit Async.Deferred.tThe result is determined when all jobs enqueued before this are finished. The
implementation adds a new job to every key currently with at least one running job
attached, so it will affect num_unfinished_jobs