Lwt is a concurrent programming library for OCaml. It provides a single data type: the promise, which is a value that will become determined in the future. Creating a promise spawns a computation. When that computation is I/O, Lwt runs it in parallel with your OCaml code.
OCaml code, including creating and waiting on promises, is run in a single thread by default, so you don't have to worry about locking or preemption. You can detach code to be run in separate threads on an opt-in basis.
Here is a simplistic Lwt program which requests the Google front page, and fails if the request is not completed in five seconds:
open Lwt.Syntax
let () =
let request =
let* addresses = Lwt_unix.getaddrinfo "google.com" "80" [] in
let google = Lwt_unix.((List.hd addresses).ai_addr) in
Lwt_io.(with_connection google (fun (incoming, outgoing) ->
let* () = write outgoing "GET / HTTP/1.1\r\n" in
let* () = write outgoing "Connection: close\r\n\r\n" in
let* response = read incoming in
Lwt.return (Some response)))
in
let timeout =
let* () = Lwt_unix.sleep 5. in
Lwt.return None
in
match Lwt_main.run (Lwt.pick [request; timeout]) with
| Some response -> print_string response
| None -> prerr_endline "Request timed out"; exit 1
(* ocamlfind opt -package lwt.unix -linkpkg example.ml && ./a.out *)
In the program, functions such as Lwt_io.write
create promises. The
let* ... in
construct is used to wait for a promise to become determined; the
code after in
is scheduled to run in a "callback." Lwt.pick
races promises
against each other, and behaves as the first one to complete. Lwt_main.run
forces the whole promise-computation network to be executed. All the visible
OCaml code is run in a single thread, but Lwt internally uses a combination of
worker threads and non-blocking file descriptors to resolve in parallel the
promises that do I/O.
Lwt compiles to native code on Linux, macOS, Windows, and other systems. It's also routinely compiled to JavaScript for the front end and Node by js_of_ocaml.
In Lwt,
Lwt
provides promises...Lwt_unix
that binds almost every Unix
system call. A higher-level module Lwt_io
provides nice I/O channels.Lwt_process
is for subprocess handling.Lwt_preemptive
spawns system threads.Lwt_react
for reactive
programming. See the table of contents on the linked manual pages!libev-dev
or libev-devel
.opam install conf-libev lwt
We are currently working on improving the Lwt documentation (drastically; we are rewriting the manual). In the meantime:
Note: much of the current manual refers to 'a Lwt.t
as "lightweight threads"
or just "threads." This will be fixed in the new manual. 'a Lwt.t
is a
promise, and has nothing to do with system or preemptive threads.
Open an issue, visit Discord chat, ask on discuss.ocaml.org, or on Stack Overflow.
Release announcements are made on discuss.ocaml.org. Watching the repo for "Releases only" is also an option.
CONTRIBUTING.md
contains tips for working on the code,
such as how to check the code out, how review works, etc. There is also a
high-level outline of the code base.