package uwt

  1. Overview
  2. Docs

Analogue to Lwt_main

exception Main_error of error * string

Main_error is thrown, when uv_run returns an error - or if lwt doesn't report any result and libuv reports, that there are no pending tasks.

exception Deferred of (exn * Printexc.raw_backtrace) list

You shouldn't raise exceptions, if you are using uwt. Always use Lwt.fail. If you throw exceptions nevertheless, uwt can usually not propagate the exceptions to the OCaml runtime immediately. The exceptions are stored internally an are re-thrown as soon as possible (Deferred). You can catch these exceptions below run.

However, uwt cannot catch all exceptions at the right moment. These exceptions are wrapped inside Fatal. Don't call any uwt function (especially run) again, if you catch such an exception below run. A workaround is currently not implemented, because only rare exceptions like Out_of_memory are 'fatal' under certain circumstances - and they usually mean you are in unrecoverable trouble anyway.

let rec main t1  =
  match Uwt.Main.run t1 with
  | exception Uwt.Main.Deferred(l) ->
    log_deferred l ; main t2 (* safe *)
  | exception Uwt.Main.Fatal(e,p) -> (* fatal, restart your process *)
    log_fatal e p ; cleanup () ; exit 2
  | exception x -> log_normal x ; main t3 (* safe *)
  | result -> let y = ... (* no error *)
exception Fatal of exn * Printexc.raw_backtrace
val enter_iter_hooks : (unit -> unit) Lwt_sequence.t
val leave_iter_hooks : (unit -> unit) Lwt_sequence.t
val yield : unit -> unit Lwt.t
val run : 'a Lwt.t -> 'a

Unlike Lwt_main.run, it's not allowed to nest calls to Uwt.Main.run. The following code is invalid, an exception Main_error will be thrown:

let help () =
   let () = Uwt.Main.run foo in
   Lwt.return_unit
in
Uwt.Main.run (help ())

And Uwt.Main.run will complain about missing work (Main_error again):

let s,t = Lwt.task () in
Uwt.Main.run s

With lwt.unix the code above could lead to a busy loop (wasting your cpu time - but it's dependend on the selected Lwt_engine). If you really want your process to run forever, without waiting for any i/o, you can create a Uwt.Timer.t that gets called repeatedly, but does nothing.

val exit_hooks : (unit -> unit Lwt.t) Lwt_sequence.t
val at_exit : (unit -> unit Lwt.t) -> unit
val cleanup : unit -> unit

Call cleanup, if you've called run and and don't intend to call run again any time soon. It will free some internally used memory, but not all.

OCaml

Innovation. Community. Security.