package lwt
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=b10689b76d20c66bd27fca4d6bba4daf7b6d77d7d4e42a9eba5579f0cb3e0941
md5=e80364e38c5fae791a6506b9c113fd29
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: 21 Jul 2017
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 = (List.hd addresses).Lwt_unix.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.
Installing
Use your system package manager to install a development libev package, 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 great 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.
Some examples are also available in Lwt's
doc/examples
.
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
What counts as a contribution to Lwt? All kinds of things make the project better, and are very much appreciated:
Asking anything. This helps everyone understand Lwt, including long-time maintainers!
Making or requesting edits to the docs, or just reading them.
Reading any issue or PR, and, optionally, adding your opinion or requesting clarification.
Explaining how to make Lwt easier to contribute to, finding problems with the contributing docs, etc.
Helping other people with Lwt, whether in this repo, or elsewhere in the world.
Writing or clarifying test cases.
And, of course, the traditional kind of contribution, picking up issues and writing code :)
Contributing to Lwt is not only for OCaml "experts!" If you are near the beginning of your OCaml journey, we'd love to give you a little help by recommending appropriate issues, or even just chatting about Lwt or OCaml. Newcomers make valuable contributions, that maintainers often learn from – not the least because newcomers bring a fresh, valuable perspective :) Don't be afraid to ask anything.
We hope you'll join us to work in a friendly community around Lwt :) On behalf of all users of, and contributors to, Lwt: Thank you! :tada:
Resources
There are several resources to help you get started:
If you'd like to ask a question, or otherwise talk, there is the contact information.
Lwt maintains a list of easy issues, which you can use to try out the code contribution workflow. This list works two ways! Please contribute to it: if you find something that needs a fix, open an issue. It might be an easy issue that another contributor would love to solve :)
CONTRIBUTING.md
contains optional tips for working on the code of Lwt, instructions on how to check the code out, and a high-level outline of the code base.The project roadmap contains a list of long-term, large-scale projects, so you can get an idea of where Lwt is headed, as a whole. Planned upcoming releases are also listed there.
Watch this repository :)
License
Lwt is released under the LGPL, with an OpenSSL linking exception. See COPYING
.
Dependencies (7)
- result
-
ppx_tools_versioned
>= "5.0.1"
-
ocaml-migrate-parsetree
< "2.0.0"
-
ocamlfind
build & >= "1.5.0"
-
jbuilder
>= "1.0+beta10"
-
cppo
build & >= "1.1.0"
-
ocaml
>= "4.02.0" & < "4.08.0"
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
- 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
< "1.0.0"
- aws-s3-lwt
- awsm-lwt
- azure-cosmos-db
- baardskeerder
- balancer
-
bap
< "1.0.0"
-
bap-server
< "0.3.0"
- bimage-lwt
-
biocaml
= "0.4.0"
-
bistro
< "0.5.0"
-
brotli
< "1.2.0"
- brozip
- builder
-
bun
>= "0.3.3"
- c3
- calculon
-
camltc
< "0.9.5"
- canary
-
capnp-rpc-lwt
< "1.2.3"
-
capnp-rpc-unix
>= "0.9.0" & < "1.2.3"
-
caqti-lwt
< "0.11.0"
-
carton-git
< "0.7.2"
- carton-lwt
- channel
-
charrua-client-lwt
< "1.2.0"
-
charrua-client-mirage
< "1.2.0"
-
charrua-core
< "0.3"
-
charrua-unix
>= "0.3" & < "0.11.0" | >= "0.11.2"
- cmdtui-lambda-term
- coclobas
-
cohttp-lwt
< "6.0.0~alpha2"
- cohttp-lwt-jsoo
- cohttp-lwt-unix
- 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"
-
cowabloga
>= "0.2.2"
-
crunch
>= "2.0.0"
- cstruct-lwt
- csv-lwt
- csvprovider
-
ctypes
>= "0.6.0" & < "0.15.0"
-
ctypes-foreign
>= "0.21.1"
-
curly
< "0.2.0"
-
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
-
dht
< "0.2.0"
-
distributed
= "0.4.0"
- dkim-mirage
-
dns
>= "0.19.1" & < "1.0.0"
-
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"
-
eliom
= "6.3.0"
- eris-lwt
- ethernet
- ezcurl-lwt
- ezirmin
-
ezjsonm
>= "0.4.2" & < "0.5.0"
- ezjsonm-lwt
- ezresto
- ezresto-directory
- faraday-lwt
- faraday-lwt-unix
-
fat-filesystem
>= "0.12.0"
- fiber-lwt
-
flowtype
>= "0.62.0" & < "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
-
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
- hardcaml-waveterm
-
hiredis
< "0.6"
- 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
- imaplet-lwt
- influxdb-lwt
-
inotify
>= "2.4"
-
inquire
< "0.3.0"
-
iocaml
< "0.4.6"
-
iocaml-kernel
>= "0.4.3"
- iocamljs-kernel
- ip2location
- ip2locationio
- ip2whois
-
ipv6-multicast
< "0.9"
- 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
- jitsu
- joolog
-
jose
< "0.9.0"
-
js_of_ocaml
< "3.0"
- js_of_ocaml-lwt
- jsoo_broadcastchannel
- jsoo_router
- jsoo_storage
-
jupyter
< "2.3.0"
-
jupyter-archimedes
< "2.3.2"
- jupyter-kernel
-
KaSim
>= "4.0.0"
-
kafka
>= "0.3" & < "0.5"
- kafka_lwt
-
ke
>= "0.5"
-
ketrew
>= "3.2.0"
-
kinetic-client
< "0.0.9"
-
lablqml
< "0.6"
- lambda-runtime
-
lambda-term
>= "1.11" & < "1.13"
- launchd
- 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
>= "0.1.2"
- lwt-pipe
- lwt-pipeline
- lwt-watcher
- lwt-zmq
- 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"
- macaque_lwt
- maki
-
mariadb
< "0.5.1"
-
markup
= "0.7.6"
- markup-lwt
- mdx
- mechaml
- metrics-influx
- metrics-lwt
- metrics-mirage
- metrics-unix
- mindstorm-lwt
-
mirage
< "0.9.1" | >= "0.10.0" & < "2.7.0"
-
mirage-block
< "1.0.0"
- mirage-block-ccm
- mirage-block-lwt
- mirage-block-ramdisk
- mirage-block-solo5
-
mirage-block-unix
< "2.8.3"
- mirage-block-xen
-
mirage-bootvar-solo5
>= "0.2.0"
- mirage-bootvar-unix
-
mirage-bootvar-xen
>= "0.4.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"
- mirage-console-lwt
-
mirage-console-solo5
>= "0.2.0"
-
mirage-console-unix
>= "2.2.0" & < "3.0.0"
-
mirage-console-xen
>= "5.0.0"
-
mirage-console-xen-backend
< "3.0.1"
- mirage-console-xen-cli
-
mirage-dns
< "3.0.0"
-
mirage-entropy
< "0.5.0"
- mirage-entropy-unix
-
mirage-entropy-xen
!= "0.2.0"
-
mirage-flow
>= "1.0.3" & < "1.2.0"
- mirage-flow-lwt
- mirage-flow-rawlink
-
mirage-flow-unix
< "2.0.0"
- mirage-fs-lwt
-
mirage-fs-unix
!= "1.2.1"
- mirage-http
- mirage-http-unix
- mirage-http-xen
- mirage-kv-lwt
-
mirage-kv-unix
< "3.0.0"
- mirage-logs
-
mirage-nat
< "3.0.0"
- mirage-net-fd
- mirage-net-lwt
- mirage-net-macosx
- mirage-net-solo5
- mirage-net-unix
- mirage-net-xen
-
mirage-os-shim
>= "3.0.0"
- mirage-profile
- mirage-protocols-lwt
-
mirage-qubes
< "0.9.4"
-
mirage-qubes-ipv4
< "0.9.4"
-
mirage-random-stdlib
>= "0.1.0"
- mirage-solo5
- mirage-stack-lwt
- mirage-time-lwt
-
mirage-time-unix
< "2.0.0"
-
mirage-types-lwt
< "3.7.1"
- mirage-unix
- mirage-vnetif
- mirage-vnetif-stack
-
mirage-www
>= "1.1.0"
- mirage-xen
- mirror
- moonpool-lwt
-
mpris
= "0.1.1"
-
mqtt
= "0.0.2"
-
mrmime
>= "0.5.0"
- multipart-form-data
-
multipart_form
>= "0.2.0" & < "0.4.0"
-
multipart_form-lwt
< "0.6.0"
- mwt
- named-pipe
- nanomsg
-
nbd
= "2.1.1" | >= "3.0.0"
- nbd-tool
- nbd-unix
- netchannel
-
nocrypto
>= "0.5.4"
- noise
- nottui-lwt
- nproc
-
nsq
< "0.2.4"
- 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
= "1.1.0" | >= "4.1.0" & < "4.7.0"
-
ocsigen-toolkit
= "1.1.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.19.0"
- opium_kernel
- order-i3-xfce
- ordma
- osc-lwt
-
oskel
>= "0.3.0"
- otetris
-
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
-
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
-
pvem_lwt_unix
>= "0.0.2"
-
qcow
< "0.11.0"
- qcow-format
- qcow-tool
-
qfs
>= "0.5" & < "0.7"
- quests
- rashell
-
rawlink
< "2.1"
- rawlink-lwt
- redis-lwt
- resource-pooling
-
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
>= "0.3.0"
- scgi
- sendmail-lwt
- sendmail-mirage
- session-cohttp-lwt
- session-cookie-lwt
-
session-postgresql-lwt
< "0.4.1"
- sessions
- shared-block-ring
-
shared-memory-ring
< "2.0.0"
- shared-memory-ring-lwt
- skkserv-lite
-
slacko
< "0.14.1"
- slipshow
- socket-daemon
- speed
-
spin
< "0.6.0"
-
spotify-web-api
< "0.2.1"
- sqlexpr
- 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" & < "4.0.0"
- telegraml
- testrunner
-
tezos-p2p
>= "11.0" & < "13.0"
-
tezos-stdlib
< "9.0"
-
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
-
tuntap
>= "1.0.0" & < "2.0.0"
- twirp_cohttp_lwt_unix
- typerex-lldb
- u2f
- usb
- uspf
- uspf-lwt
- uspf-mirage
-
utop
>= "1.4.0"
-
uwt
>= "0.0.2"
-
vchan
>= "0.9.6" & < "2.0.0" | >= "2.0.3"
- vchan-unix
- vchan-xen
- vercel
-
vhd-format
>= "0.6.0" & < "0.9.1"
-
vhd-format-lwt
< "0.12.0"
-
vhd-tool
< "0.12.0"
- vmnet
-
vpnkit
>= "0.1.1"
-
vue-jsoo
< "0.3"
- webauthn
-
websocket
< "2.3"
-
websocket-lwt
= "2.11"
- xe-unikernel-upload
-
xen-api-client
< "0.9.14"
- xen-block-driver
- xen-evtchn
- xen-evtchn-unix
- xen-gnt
-
xen-gnt-unix
>= "4.0.2"
- xenctrl
- xenstore
- xenstore_transport
- xentropyd
- xlsx2csv
-
yurt
!= "0.3" & < "0.5"
- zarr-lwt
- zbar
- zmq-lwt
Conflicts (2)
-
dune
>= "1.7.0"
-
ocaml-variants
= "4.02.1+BER"