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 ()
.