What's new in Lwt 2.4.0

Streams

New implementation of the module Lwt_stream. The main differences are:

Bounded push streams are created using the function Lwt_stream.​create_bounded which returns an object to control the push end-point of the stream.

It is also possible to add a reference to a value in a stream, this is especially useful when it is just used as a proxy for another data structure. For example to create a stream from a react event one can write:

let stream, push, set_ref = Lwt_stream.create_with_reference () in
set_ref (map (fun x -> push (Some x)) event);
stream

This way the event pushing occurences of event to the stream won't be garbage collected before stream.

Change of behavior

The behavior when accessing a stream from multiple threads at the same time changed. When several threads are waiting on an empty stream, and new elements become available:

For example with the following code:

let st, push = Lwt_stream.create () in
let t1 = Lwt_stream.get st in
let t2 = Lwt_stream.get st in
push (Some 1);
push (Some 2);
Lwt.bind t1 (fun x1 -> Lwt.bind t2 (fun x2 -> Lwt.return (x1, x2)))

the result with Lwt < 2.4.0 is (1, 2), and with Lwt >= 2.4.0 it is (1, 1).

The behavior in this case was not specified.

Lwt.async

A new primitive Lwt.​async has been added to the module Lwt. It is a better replacement of the old Lwt.​ignore_result function (kept for compatibility):

val async : (unit -> 'a t) -> unit

If the function given as argument raises an exception or the resulting thread fails, the exception is given to Lwt.async_exception_hook, which defaults to printing the exception and exiting the program.

The goal of async is just to ensure that unexpected errors are reported; threads whose result is ignored should raise no exception in a robust program (i.e. all errors should be handled).

Cancelable threads

Now functions registered with Lwt.​on_cancel are guaranteed to be called first. For example, in the following code:

let waiter, wakener = Lwt.task () in
Lwt.on_cancel waiter f;
let t = Lwt.bind waiter g in
...

it is guaranteed that if waiter is canceled then f will be called before g.

Lwt_preemptive.run_in_main

If you want to execute some Lwt code from another preemptive thread than the main one you can now use the function Lwt_preemptive.​run_in_main. It will send the function to the main thread which will execute it and send back the result.

val run_in_main : (unit -> 'a Lwt.t) -> 'a

Windows

The module Lwt_process can now be used on Windows.

Unix jobs

API for unix jobs have been simplified, now only one C external is needed. The job structure contains one more field result containing the C callback responsible for freeing allocated data and returning the result as an OCaml value.

From the OCaml side, you must call the function Lwt_unix.​run_job instead of Lwt_unix.​execute_job.