module Main:sig..end
Analogue of 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 Fatal of exn * Printexc.raw_backtrace
You shouldn't raise exceptions, if you are using uwt. Always use
Lwt.fail. If you throw exceptions nevertheless, uwt can
sometimes not propagate the exceptions to the OCaml runtime
immediately. This applies for example to exceptions that occur
inside iterative callbacks (like Stream.read_start,
Timer.start, Poll.start, etc. ). They are passed to
Lwt.async_exception_hook instead. If your Lwt.async_exception_hook
then also throws an exception, it is silently ignored.
However, uwt cannot catch all exceptions at the right
moment. Don't call any uwt function (especially Uwt.Main.run) again,
if you catch such an exception below Uwt.Main.run. A workaround is
currently not implemented, because only rare exceptions like
Out_of_memory and Stackoverflow are 'fatal' under rare
conditions - and they usually mean you are in unrecoverable
trouble anyway.
let rec main t1 =
match Uwt.Main.run t1 with
| 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 *)
val yield : unit -> unit Lwt.tyield () is a threads which suspends itself and then resumes
as soon as possible and terminates.
val run : 'a Lwt.t -> 'aUnlike 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 depends 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 enter_iter_hooks : (unit -> unit) Lwt_sequence.tFunctions that are called before the main iteration.
val leave_iter_hooks : (unit -> unit) Lwt_sequence.tFunctions that are called after the main iteration.
val exit_hooks : (unit -> unit Lwt.t) Lwt_sequence.tSets of functions executed just before the program exit.
Notes:
Don't use Pervasives.exit together with uwt - or only use it outside any
function that is passed to Uwt.Main.run. Pervasives.exit
interrupts the normal code flow and will leave libuv's internal
state in an inconsistent state. Your exit hooks will never be called.
val at_exit : (unit -> unit Lwt.t) -> unitat_exit hook adds hook at the left of exit_hooks
val cleanup : unit -> unitCall Uwt.Main.cleanup, if you've called Uwt.Main.run and and don't intend to
call Uwt.Main.run again any time soon. It will free some internally used
memory, but not all.