package tezos-stdlib
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=6b33e0549574c89a63538c94ce5555dd141e3c0fb5d934abff07d702fa3244d2
sha512=681a197baabec6e2f806871d43490382243207518f8fcf932741cd314d8717e46db2b6a5adc222f8726083a5dd911083b4931b7e878ab815f8f1a32763d1bf93
doc/tezos-stdlib/Tezos_stdlib/Lwt_utils/index.html
Module Tezos_stdlib.Lwt_utils
val never_ending : unit -> 'a Lwt.t
val worker :
string ->
on_event:(string -> [ `Ended | `Failed of string | `Started ] -> unit Lwt.t) ->
run:(unit -> unit Lwt.t) ->
cancel:(unit -> unit Lwt.t) ->
unit Lwt.t
worker name ~on_event ~run ~cancel
internally calls run ()
(which returns a promise p
) and returns its own promise work
. If p
becomes fulfilled, then work
also becomes fulfilled. If p
becomes rejected then cancel ()
is called and, once its promise is resolved, work
is fulfilled. This gives the opportunity for the function cancel
to clean-up some resources.
The function on_event
is called at different times (start, failure, end) and is mostly meant as a logging mechanism but can also be used for other purposes such as synchronization between different workers.
If the promises returned by on_event
or cancel
raise an exception or become rejected, the exception/failure is simply ignored and the promise is treated as having resolved anyway.
Note that the promise work
returned by the worker
function is not cancelable. If you need to cancel the promise returned by run
, you need to embed your own synchronization system within run
. E.g.,
let p, r = Lwt.wait in let run () = let main = … in Lwt.pick [main ; p] in
Evaluates fold_left_s on a batch of n
elements and returns a pair containing the result of the first batch and the unprocessed elements
val dont_wait : (exn -> unit) -> (unit -> unit Lwt.t) -> unit
dont_wait handler f
calls f ()
and essentially ignores the returned promise. In particular it does not wait for the promise to resolve.
dont_wait
is meant as an alternative to Lwt.async
. The former requires an explicit, local exception handler whereas the latter uses a global handler that is set by side-effects.
CAVEAT!
Note that, because of the semantics of execution in Lwt, the evaluation of f ()
is immediate and some progress towards the resolution of the promise may happen immediately. Specifically, the progress towards the resolution of the promise p
returned by f ()
is made until the point where it yields. At that point, control comes back to the caller of dont_wait
and continues. More concretely, consider the order of the side-effects in the following piece of code and in particular how the second side-effect in the order of execution is within the promise created by dont_wait
.
side_effect (); (* first *) dont_wait (fun exc -> ..) (fun () -> side_effect (); (* second *) Lwt.pause () >>= fun () -> side_effect (); (* delayed *) ..); side_effect (); (* third *)
If you want to delay any progress towards promise resolution being made (e.g., if you need strong guarantees about side-effects because you are in a critical section), then you need to add an explicit cooperation point. You can use Lwt.pause
at the very beginning of the promise you pass to dont_wait
: dont_wait handler (fun () -> Lwt.pause () >>= fun () -> ..)
.
With this pattern, in the expression dont_wait handler (fun () -> Lwt.pause () >>= f)
, the anonymous lambda ((fun () -> …)
) is called immediately. However, when this call is evaluated, the call to pause
immediately suspend progress towards the resolution of the promise, delaying the call f ()
.