Concurrent tasks in Lwt

I don’t think that this is exactly your code. For one thing it doesn’t type because Lwt_main.run expects a promise. But more importantly, this will not do any work in the tasks that’s beyond I/O or pauses/yield. E.g., consider the code below

let () =
  Lwt_main.run @@
    let open Lwt.Syntax in
    ignore (let* () = Lwt_unix.sleep 5. in print_endline "waited 5"; Lwt.return ());
    ignore (let* () = Lwt_unix.sleep 7. in print_endline "waited 7"; Lwt.return ());
    Lwt.return ()

The executable exits immediately, no printing happens.

That’s because Lwt_main.run simply “awaits” for the given promise to resolve at which point it returns the value into the OCaml world and the execution of the program continues as normal (i.e., as a non-Lwt program would).

If there are pending I/O jobs and unresolved promises in the scheduler then they are simply ignored.

For a server, you can pass your main-loop to run (in the case of a server, the loop that calls accepts, spawns a task and then calls accept again, indefinitely). Or sometimes you can just pass a never-resolving promise (fst (Lwt.task ()) or similar).


Regarding exception management, I’d recommend that you use Lwt.dont_wait rather than on_failure+ignore. It should be roughly equivalent but it will force you to have a unit promise and to wrap your promise inside a lambda which avoids exceptions leaking out.

E.g., the following will raise “outside of the promise” and the handler won’t be called

let p =
  if param < 0 then raise (Invalid_argument "");
  let* …
in
Lwt.on_failure p (fun exn -> …);
ignore p;

whereas the same code with dont_wait will pass the exception to the handler.