package lwt
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=51569cb509c1cbc2bf52e782fe0808da22d18ddb9329a066ada5113095ab238c
md5=3bbde866884e32cc7a9d9cbd1e52bde3
Description
A promise is a value that may become determined in the future.
Lwt provides typed, composable promises. Promises that are resolved by I/O are resolved by Lwt in parallel.
Meanwhile, OCaml code, including code creating and waiting on promises, runs in a single thread by default. This reduces the need for locks or other synchronization primitives. Code can be run in parallel on an opt-in basis.
Published: 10 Apr 2018
README
Lwt
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." 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.
Overview
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 and BuckleScript.
In Lwt,
The core library
Lwt
provides promises......and a few pure-OCaml helpers, such as promise-friendly mutexes, condition variables, and mvars.
There is a big Unix binding,
Lwt_unix
that binds almost every Unix system call. A higher-level moduleLwt_io
provides nice I/O channels.Lwt_process
is for subprocess handling.Lwt_preemptive
spawns system threads.The PPX syntax allows using all of the above without going crazy!
There are also some other helpers, such as
Lwt_react
for reactive programming. See the table of contents on the linked manual pages!
Installing
Use your system package manager to install a development libev package. It is often called
libev-dev
orlibev-devel
.opam install conf-libev lwt
Documentation
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.
Contact
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!
Subscribe to the announcements issue to get news about Lwt releases. It is less noisy than watching the whole repository. Announcements are also made in /r/ocaml, on the OCaml mailing list, and on discuss.ocaml.org.
Contributing
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.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.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!
License
Lwt is released under the LGPL, with an OpenSSL linking exception. See COPYING
.
Related Libraries
alcotest A lightweight framework for unit testing
angstrom A library for building parsers with a focus on efficiency, concurrency, and reusability
cohttp A lightweight library for writing HTTP clients and servers
cstruct A library and syntax extension for interop with C-like structures
ezjsonm A library for easy interop with JSON
faraday A library for fast and memory-efficient serialization
logs A logging library with reporting decoupled from logging
lwt-parallel A library for distributed computing
Dependencies (5)
Dev Dependencies
None
-
0install
>= "2.14"
- albatross
- alcotest-lwt
- alcotest-mirage
- ambient-context-lwt
-
amqp-client
>= "0.9.0" & < "1.0.2" | >= "1.1.0"
-
amqp-client-lwt
>= "2.0.1"
- angstrom-lwt-unix
- anthill
- anycache-lwt
-
arakoon
< "1.8.6" | >= "1.8.8"
- archi-lwt
-
arp
>= "2.3.1"
- arp-mirage
- awa-lwt
-
awa-mirage
< "0.2.0"
- aws-lwt
- aws-s3-lwt
- awsm-lwt
- azure-cosmos-db
- baardskeerder
- balancer
-
bap
< "1.0.0"
-
bap-server
!= "0.2.0"
- bimage-lwt
-
biocaml
= "0.4.0"
-
bistro
>= "0.4.0"
- brozip
- builder
-
bun
>= "0.3.3"
- c3
- calculon
- caldav
-
camltc
= "0.9.5" | >= "0.9.7.0"
- canary
-
capnp-rpc-lwt
< "1.2.3"
-
capnp-rpc-unix
>= "0.9.0" & < "1.2.3"
-
caqti-lwt
>= "0.11.0" & < "2.0.1"
-
carton-git
< "0.7.2"
- carton-lwt
- cf-lwt
- channel
-
charrua-client
>= "1.3.0"
- charrua-client-lwt
- charrua-client-mirage
-
charrua-core
< "0.3"
-
charrua-unix
>= "0.3" & != "0.10"
- cmdtui-lambda-term
- coclobas
-
cohttp-lwt
< "6.0.0~alpha2"
- cohttp-lwt-jsoo
-
cohttp-lwt-unix
>= "1.1.1"
- cohttp-lwt-unix-nossl
- cohttp-lwt-unix-ssl
- cohttp-mirage
- comby
- comby-semantic
- conan-lwt
-
conduit-lwt
< "7.0.0"
-
conduit-lwt-unix
< "7.0.0"
-
core-lwt
>= "0.3.0"
-
cowabloga
>= "0.2.2"
-
crunch
>= "2.0.0"
- cstruct-lwt
- csv-lwt
- csvprovider
-
ctypes
>= "0.15.0" & < "0.21.1"
-
ctypes-foreign
>= "0.21.1"
-
current_docker
< "0.6.4"
-
current_examples
< "0.6.4"
-
current_git
< "0.6.4"
-
current_github
< "0.6.4"
-
current_gitlab
< "0.6.4"
-
current_ocluster
< "0.2"
-
current_slack
< "0.6.4"
-
current_web
< "0.6.4"
- DkSDKFFIOCaml_Std
- dap
-
data-encoding
< "0.1.1"
- datakit
- datakit-bridge-github
- datakit-bridge-local-git
- datakit-ci
-
datakit-client
>= "0.11.0"
- datakit-github
- datakit-server
-
devkit
>= "0.6"
-
dht
< "0.2.0"
- distributed-lwt
- dkim-mirage
-
dns
>= "0.19.1" & < "0.20.1"
-
dns-cli
>= "4.6.3"
-
dns-forward
>= "0.9.0"
- dns-forward-lwt-unix
- dns-lwt
- dnssd
- docker_hub
- dream
- dream-httpaf
- dream-pure
- dropbox
- dune_watch
-
earlybird
< "1.0.0"
-
elasticsearch-cli
>= "0.4"
- eris-lwt
- ethernet
- ez_api
- ezcurl-lwt
- ezirmin
-
ezjsonm
>= "0.4.2" & < "0.5.0"
- ezjsonm-lwt
- ezresto
- ezresto-directory
- faraday-lwt
-
faraday-lwt-unix
>= "0.6.0"
-
fat-filesystem
>= "0.12.0"
- fiber-lwt
-
flowtype
>= "0.72.0"
-
frenetic
< "2.0.0"
- fswatch_lwt
- fuseau-lwt
- gamepad
- gdb
-
gdbprofiler
>= "0.3"
-
git
!= "1.4.3" & != "1.7.2"
- git-paf
-
git-unix
= "1.11.1" | >= "3.0.0" & < "3.10.0"
- github
-
github-hooks
< "0.2.0" | >= "0.4.0"
-
github-unix
>= "4.4.0"
- gitlab-unix
-
gluten-lwt
< "0.4.0"
-
gluten-lwt-unix
< "0.4.0"
-
gluten-mirage
< "0.4.0"
- graphql-lwt
- gufo
- h1
- h1-lwt-unix
-
h2-lwt
< "0.10.0"
-
h2-lwt-unix
< "0.10.0"
- h2-mirage
- happy-eyeballs-lwt
- happy-eyeballs-mirage
-
hardcaml
< "1.1.0"
-
hardcaml-examples
>= "0.3.0"
- hardcaml-framework
- hiredis
- hl_yaml
-
horned_worm
< "0.3.1"
- http-lwt-client
-
http-multipart-formdata
>= "2.0.0" & < "3.0.0"
- http2https
- httpaf-lwt-unix
- httpun-lwt
- httpun-mirage
- httpun-ws-lwt
-
hvsock
>= "1.0.2"
-
i3ipc
>= "0.1.4"
- imaplet-lwt
- influxdb-lwt
-
inotify
>= "2.4"
-
inquire
< "0.3.0"
-
iocaml
< "0.4.6"
-
iocaml-kernel
>= "0.4.3" & < "0.4.6"
- iocamljs-kernel
- ip2location
- ip2locationio
- ip2whois
- ipv6-multicast-lwt
- irc-client-lwt
- irc-client-lwt-ssl
- irc-client-tls
-
irmin
< "0.9.6" | = "0.9.10" | >= "0.11.0" & < "2.7.0"
-
irmin-bench
< "2.7.0"
-
irmin-chunk
< "2.7.0"
-
irmin-containers
< "2.7.0"
-
irmin-fs
>= "2.3.0" & < "2.7.0"
-
irmin-git
>= "2.3.0" & < "2.7.0"
-
irmin-graphql
>= "2.3.0" & < "2.7.0"
-
irmin-http
>= "2.3.0" & < "2.7.0"
- irmin-indexeddb
-
irmin-layers
< "2.7.0"
-
irmin-mem
>= "2.3.0"
-
irmin-mirage-git
>= "2.3.0" & < "2.7.0"
-
irmin-mirage-graphql
>= "2.3.0" & < "2.7.0"
-
irmin-pack
< "2.7.0"
-
irmin-test
>= "2.3.0" & < "2.7.0"
-
irmin-unix
>= "2.3.0" & < "2.7.0"
-
irmin-watcher
>= "0.3.0"
- jitsu
- joolog
-
jose
< "0.9.0"
-
js_of_ocaml
< "2.5"
-
js_of_ocaml-lwt
>= "3.2.0"
- jsoo_broadcastchannel
- jsoo_router
- jsoo_storage
-
jupyter
>= "2.3.0"
-
jupyter-kernel
>= "0.4"
-
kafka
>= "0.3" & < "0.5"
- kafka_lwt
-
ke
>= "0.5"
-
ketrew
>= "3.2.0"
-
kinetic-client
< "0.0.3" | >= "0.0.9"
- kubecaml
-
lablqml
< "0.6"
- lambda-runtime
-
lambda-term
>= "1.13" & < "3.0.0" | = "3.2.0"
- launchd
-
learn-ocaml
>= "0.13.0"
-
learn-ocaml-client
>= "0.13.0"
- letsencrypt
- letsencrypt-app
- letsencrypt-dns
- libres3
-
links
< "0.9.5"
-
lru_cache
< "v0.16.0"
- lwt-binio
- lwt-canceler
- lwt-dllist
- lwt-exit
-
lwt-parallel
>= "1.0.0"
- lwt-pipe
- lwt-pipeline
- lwt-watcher
-
lwt-zmq
< "1.0.0" | >= "2.0.1"
- lwt_camlp4
-
lwt_domain
< "0.3.0"
-
lwt_eio
< "0.4"
-
lwt_glib
>= "1.0.1"
-
lwt_log
>= "1.1.0"
- lwt_named_threads
- lwt_ppx
- lwt_ppx_let
-
lwt_react
>= "1.0.1"
-
lwt_ssl
>= "1.0.1"
-
mariadb
< "0.5.1"
-
markup
= "0.7.6"
- markup-lwt
- mdx
- mechaml
- metrics-influx
- metrics-lwt
- metrics-mirage
- metrics-unix
- mindstorm-lwt
-
mirage
>= "0.4.1" & != "0.6.1" & < "0.8.0" | >= "0.10.0" & < "2.7.0"
-
mirage-block
< "1.0.0" | >= "2.0.0"
- mirage-block-ccm
- mirage-block-combinators
- mirage-block-lwt
- mirage-block-ramdisk
- mirage-block-solo5
-
mirage-block-unix
< "2.3.0" | = "2.8.2"
- mirage-block-xen
-
mirage-bootvar-solo5
>= "0.2.0"
- mirage-bootvar-unix
-
mirage-bootvar-xen
>= "0.4.0"
-
mirage-channel
>= "4.0.0"
- mirage-channel-lwt
-
mirage-clock-freestanding
< "3.0.0"
- mirage-clock-lwt
-
mirage-clock-unix
>= "1.2.0" & < "3.0.0"
-
mirage-console
>= "2.1.1" & < "2.2.0" | >= "3.0.0"
- mirage-console-lwt
-
mirage-console-solo5
>= "0.2.0"
-
mirage-console-unix
>= "2.2.1"
-
mirage-console-xen
>= "5.0.0"
- mirage-console-xen-backend
- mirage-console-xen-cli
- mirage-crypto-entropy
-
mirage-crypto-rng
>= "0.7.0" & < "0.11.0"
- mirage-crypto-rng-lwt
-
mirage-crypto-rng-mirage
>= "0.8.8"
-
mirage-device
>= "2.0.0"
-
mirage-dns
< "3.0.0"
- mirage-entropy
-
mirage-flow
>= "1.0.3" & < "1.2.0" | >= "2.0.0"
- mirage-flow-combinators
- mirage-flow-lwt
- mirage-flow-rawlink
- mirage-flow-unix
-
mirage-fs
>= "3.0.0"
- mirage-fs-lwt
-
mirage-fs-unix
< "1.1.1" | >= "1.3.0"
- mirage-http
- mirage-http-unix
- mirage-http-xen
-
mirage-kv
>= "3.0.0"
- mirage-kv-lwt
-
mirage-kv-unix
< "3.0.0"
- mirage-logs
-
mirage-nat
< "3.0.0"
-
mirage-net
>= "3.0.1"
- mirage-net-fd
- mirage-net-lwt
- mirage-net-macosx
- mirage-net-solo5
-
mirage-net-unix
>= "2.2.0"
- mirage-net-xen
-
mirage-os-shim
>= "3.0.0"
- mirage-profile
-
mirage-protocols
>= "4.0.0" & < "8.0.0"
- mirage-protocols-lwt
-
mirage-qubes
< "0.2" | >= "0.4" & < "0.9.4"
-
mirage-qubes-ipv4
< "0.9.4"
-
mirage-random-stdlib
>= "0.1.0"
-
mirage-runtime
>= "3.7.0"
- mirage-solo5
-
mirage-stack
>= "2.0.0" & < "4.0.0"
- mirage-stack-lwt
-
mirage-time
>= "2.0.0"
- mirage-time-lwt
- mirage-time-unix
-
mirage-types-lwt
< "3.7.1"
-
mirage-unix
>= "3.0.0"
- mirage-vnetif
- mirage-vnetif-stack
-
mirage-www
>= "1.1.0"
- mirage-xen
- mirror
- moonpool-lwt
-
mqtt
= "0.0.2"
-
mrmime
>= "0.5.0"
-
multipart-form-data
>= "0.2.0"
-
multipart_form
>= "0.2.0" & < "0.4.0"
-
multipart_form-lwt
< "0.6.0"
- mwt
-
named-pipe
>= "0.3"
- nanomsg
-
nbd
= "2.1.1" | >= "3.0.0"
- nbd-tool
- nbd-unix
- netchannel
-
nocrypto
>= "0.5.4"
- noise
- nottui-lwt
- nproc
-
nsq
>= "0.4.0"
- obrowser
-
obuilder
< "0.4"
-
obus
>= "1.1.8" & < "1.2.1"
-
ocaml-variants
>= "4.00.1+mirage-unix" & < "4.00.1+open-types"
-
ocluster
< "0.2"
-
ocluster-api
< "0.2"
- ocplib-concur
- ocplib-resto
-
ocsigen-start
>= "4.1.0" & < "4.7.0"
-
ocsigenserver
>= "2.10"
-
odoc
>= "2.0.0" & < "2.1.0"
- ojquery
-
ojs-base
< "0.6.0"
-
opam-compiler
< "0.2.0"
-
opam-publish
= "0.3.5"
- opam-sync-github-prs
-
openflow
< "0.2.0"
-
opium
>= "0.11.0" & != "0.16.0" & < "0.19.0"
- opium_kernel
- opomodoro
- order-i3-xfce
-
ordma
>= "0.0.3"
- osc-lwt
-
oskel
>= "0.3.0"
-
ounit-lwt
< "2.2.0"
- ounit2-lwt
-
ox
< "1.1.0"
- paf
- paf-cohttp
- passage
-
pcap-format
>= "0.3.3" & < "0.5.0"
- pgx_lwt
- pgx_lwt_mirage
-
pgx_lwt_unix
< "2.0"
-
plotkicadsch
>= "0.4.0"
-
ppx_defer
>= "0.4.0"
- ppx_deriving_rpc
- ppx_json_types
- ppx_netblob
- ppx_rapper_lwt
- ppx_sqlexpr
- prof_spacetime
- prometheus
- prometheus-app
- promise_jsoo_lwt
-
protocol-9p
>= "0.10.0"
- protocol-9p-unix
-
qcow
>= "0.8.1"
-
qcow-format
< "0.3"
- qcow-tool
-
qfs
= "0.5" | >= "0.7"
- quests
-
rawlink
>= "1.0" & < "2.1"
- rawlink-lwt
- redis-lwt
-
resource-pooling
>= "0.3.2"
-
resp
>= "0.10.0"
-
resp-mirage
>= "0.10.0"
-
resp-unix
>= "0.10.0"
- resto
- resto-cohttp-client
- resto-cohttp-self-serving-client
- resto-cohttp-server
- resto-directory
- riak
- ringo-lwt
- river
-
rpc
>= "1.5.1" & < "7.1.0"
- rpclib-js
- rpclib-lwt
- sanddb
- scgi
- sendmail-lwt
- sendmail-mirage
- serial
- session-cohttp-lwt
- session-cookie-lwt
-
session-postgresql-lwt
>= "0.4.1"
- sessions
-
shared-block-ring
< "2.3.0" | >= "3.0.0"
-
shared-memory-ring
>= "1.2.0" & < "2.0.0"
- shared-memory-ring-lwt
- slacko
- slipshow
-
smtml
>= "0.3.1"
-
socket-daemon
< "0.3.0"
- speed
-
spin
< "0.6.0"
-
spotify-web-api
< "0.2.1"
-
sqlexpr
= "0.7.1" | >= "0.9.0"
- statsd-client
-
stog
>= "0.16.0" & < "0.19.0"
-
syndic
>= "1.4" & < "1.6.0"
-
tar-format
>= "0.4.1"
-
tar-mirage
< "2.2.0"
-
tar-unix
< "3.0.0"
-
tcpip
>= "3.1.1"
- teash
- telegraml
-
tezos-p2p
< "8.0" | >= "11.0" & < "13.0"
-
tezos-stdlib
< "9.3"
-
tezos-stdlib-unix
< "9.0"
- tftp
- themoviedb
- timmy-lwt
-
tls
>= "0.10.1" & < "0.16.0"
-
tls-lwt
< "0.17.4"
- tls-mirage
-
tlstunnel
>= "0.2.0"
- transmission-rpc
-
tube
>= "4.3.0"
-
tuntap
>= "1.0.0" & < "2.0.0"
- twirp_cohttp_lwt_unix
- typerex-lldb
- u2f
- uspf
- uspf-lwt
- uspf-mirage
-
utop
>= "1.4.0"
-
uwt
>= "0.3.0"
-
vchan
>= "0.9.7" & < "2.0.0" | >= "2.0.3"
- vchan-unix
- vchan-xen
- vercel
-
vhd-format
>= "0.7.0" & < "0.8.0"
-
vhd-format-lwt
>= "0.12.0"
-
vhd-tool
< "0.12.0"
-
vmnet
>= "1.3.2"
-
vpnkit
>= "0.2.0"
-
vue-jsoo
< "0.3"
- webauthn
-
websocket
< "2.3"
- xe-unikernel-upload
-
xen-api-client
< "0.9.14"
- xen-block-driver
-
xen-evtchn
!= "1.0.6"
- xen-evtchn-unix
-
xen-gnt
>= "2.2.3"
-
xen-gnt-unix
>= "4.0.2"
-
xenctrl
< "0.9.29" | >= "0.9.32"
-
xenstore
>= "1.3.0"
-
xenstore_transport
>= "1.0.0"
- xentropyd
- xlsx2csv
-
yurt
< "0.3"
- zarr-lwt
- zbar
- zmq-lwt
Conflicts (1)
-
ocaml-variants
= "4.02.1+BER"