Lwt is OCaml's concurrent programming library. 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:
let () = let request = let%lwt 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%lwt () = write outgoing "GET / HTTP/1.1\r\n" in let%lwt () = write outgoing "Connection: close\r\n\r\n" in let%lwt response = read incoming in Lwt.return (Some response))) in let timeout = let%lwt () = 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 -package lwt_ppx -linkpkg -o request example.ml ./request *)
In the program, functions such as
Lwt_io.write create promises. The
let%lwt ... in construct is used to wait for a promise to become determined;
the code after
in is scheduled to run in a "callback."
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.
- The core library
- ...and a few pure-OCaml helpers, such as promise-friendly mutexes, condition variables, and mvars.
- There is a big Unix binding,
Lwt_unixthat binds almost every Unix system call. A higher-level module
Lwt_ioprovides nice I/O channels.
Lwt_processis for subprocess handling.
Lwt_preemptivespawns system threads.
- The PPX syntax allows using all of the above without going crazy!
- There are also some other helpers, such as
Lwt_reactfor reactive programming. See the table of contents on the linked manual pages!
- Use your system package manager to install a development libev package.
It is often called
opam install conf-libev lwt
We are currently working on improving the Lwt documentation (drastically; we are rewriting the manual). In the meantime:
- The current manual can be found here.
- Mirage has a nicely-written Lwt tutorial.
- An example of a simple server written in Lwt.
- Concurrent Programming with Lwt is a nice source of Lwt examples. They are translations of code from the excellent Real World OCaml, but are just as useful if you are not reading the book.
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 Gitter chat, ask in #ocaml, on discuss.ocaml.org, or on Stack Overflow. Please do ask! Even apparently simple questions often end up educating other users, not to mention enlightening the maintainers!
- We maintain easy starter issues. These are thoroughly explained and hyperlinked. We hope that this makes working on Lwt accessible even to relative OCaml beginners :)
CONTRIBUTING.mdcontains 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.
- The overall development plan can be found in the roadmap.
- Ask us anything, whether it's about working on Lwt, or any question at all about it :)
- The documentation always needs proofreading and fixes.
- Despite a lot of progress, Lwt still needs more tests.
- You are welcome to pick up any other issue, review a PR, add your opinion, etc.
- Any feedback is welcome, including how to make contributing easier!