Lwt_switch
Lwt switches
Switch has two goals:
For example, consider the following interface:
type id
val free : id -> unit Lwt.t
val f : unit -> id Lwt.t
val g : unit -> id Lwt.t
val h : unit -> id Lwt.t
Now you want to call f
, g
and h
in parallel. You can simply do:
lwt idf = f () and idg = g () and idh = h () in
...
However, one may want to handle possible failures of f ()
, g ()
and h ()
, and disable all allocated resources if one of these three threads fails. This may be hard since you have to remember which one failed and which one returned correctly.
Now if we change the interface a little bit:
val f : ?switch : Lwt_switch.t -> unit -> id Lwt.t
val g : ?switch : Lwt_switch.t -> unit -> id Lwt.t
val h : ?switch : Lwt_switch.t -> unit -> id Lwt.t
the code becomes:
Lwt_switch.with_switch (fun switch ->
lwt idf = f ~switch ()
and idg = g ~switch ()
and idh = h ~switch () in
...
)
val create : unit -> t
create ()
creates a new switch.
with_switch fn
is fn switch
, where switch
is a fresh switch that is turned off when the callback thread finishes (whether it succeeds or fails).
val is_on : t -> bool
is_on switch
returns true
if the switch is currently on, and false
otherwise.
turn_off switch
turns off the switch. It calls all registered hooks, waits for all of them to terminate, then returns. If one of the hooks failed, it will fail with the exception raised by the hook. If the switch is already off, it does nothing.
val check : t option -> unit
check switch
does nothing if switch
is None
or contains an switch that is currently on, and raises Off
otherwise.