package lwt

  1. Overview
  2. Docs

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: 19 Apr 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

opam install lwt

Documentation

The manual can be found here. There are also some examples available in doc/examples.

Note: much of the manual still 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, email the maintainer, or ask in #ocaml. If you think enough people will be interested in the answer, it is also possible to ask on Stack Overflow.

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 and on the OCaml mailing list.


Contributing

Lwt is a very mature library, but there is considerable room for improvement. Contributions are welcome. To clone the source and install a development version,

opam source --dev-repo --pin lwt

This will also install the development dependency OASIS.

A list of project suggestions and a roadmap can be found on the wiki.


License

Lwt is released under the LGPL, with the OpenSSL linking exception. See COPYING.

Dependencies (8)

  1. ppx_tools build
  2. base-no-ppx
  3. cppo_ocamlbuild build
  4. cppo build & >= "1.1.0"
  5. result
  6. ocamlbuild build
  7. ocamlfind build & >= "1.5.0"
  8. ocaml >= "4.02.0" & < "4.08.0"

Dev Dependencies

None

  1. 0install >= "2.14"
  2. albatross
  3. alcotest-lwt
  4. alcotest-mirage
  5. ambient-context-lwt
  6. amqp-client >= "0.9.0" & < "1.0.2" | >= "1.1.0"
  7. amqp-client-lwt
  8. angstrom-lwt-unix
  9. anthill
  10. anycache-lwt
  11. arakoon < "1.8.6" | >= "1.8.8"
  12. archi-lwt
  13. arp >= "2.3.1"
  14. arp-mirage
  15. awa-lwt
  16. awa-mirage < "0.2.0"
  17. aws < "1.0.0"
  18. aws-s3-lwt
  19. awsm-lwt
  20. azure-cosmos-db
  21. baardskeerder
  22. balancer
  23. bap < "1.0.0"
  24. bap-server < "0.3.0"
  25. bimage-lwt
  26. biocaml = "0.4.0"
  27. bistro < "0.5.0"
  28. brotli < "1.2.0"
  29. brozip
  30. builder
  31. bun >= "0.3.3"
  32. c3
  33. calculon
  34. camltc < "0.9.5"
  35. canary
  36. capnp-rpc-lwt < "1.2.3"
  37. capnp-rpc-unix >= "0.9.0" & < "1.2.3"
  38. caqti-lwt < "0.11.0"
  39. carton-git
  40. carton-lwt
  41. channel
  42. charrua-client-lwt < "1.2.0"
  43. charrua-client-mirage < "1.2.0"
  44. charrua-core < "0.3"
  45. charrua-unix >= "0.3" & < "0.11.0" | >= "0.11.2"
  46. cmdtui-lambda-term
  47. coclobas
  48. cohttp-lwt < "6.0.0~alpha2"
  49. cohttp-lwt-jsoo
  50. cohttp-lwt-unix
  51. cohttp-lwt-unix-nossl
  52. cohttp-lwt-unix-ssl
  53. cohttp-mirage
  54. comby
  55. comby-semantic
  56. conan-lwt
  57. conduit-lwt
  58. conduit-lwt-unix
  59. cowabloga >= "0.2.2"
  60. crunch >= "2.0.0"
  61. cstruct-lwt
  62. csv-lwt
  63. csvprovider
  64. ctypes >= "0.6.0" & < "0.15.0"
  65. ctypes-foreign >= "0.21.1"
  66. curly < "0.2.0"
  67. current_docker < "0.6.4"
  68. current_examples < "0.6.4"
  69. current_git < "0.6.4"
  70. current_github < "0.6.4"
  71. current_gitlab < "0.6.4"
  72. current_ocluster < "0.2"
  73. current_slack < "0.6.4"
  74. current_web < "0.6.4"
  75. DkSDKFFIOCaml_Std
  76. dap
  77. data-encoding < "0.1.1"
  78. datakit
  79. datakit-bridge-github
  80. datakit-bridge-local-git
  81. datakit-ci
  82. datakit-client >= "0.11.0"
  83. datakit-github
  84. datakit-server
  85. devkit
  86. dht < "0.2.0"
  87. distributed = "0.4.0"
  88. dkim-mirage
  89. dns >= "0.19.1" & < "1.0.0"
  90. dns-forward >= "0.9.0"
  91. dns-forward-lwt-unix
  92. dns-lwt
  93. dnssd
  94. docker_hub
  95. dream
  96. dream-httpaf
  97. dream-pure
  98. dropbox
  99. dune_watch
  100. earlybird < "1.0.0"
  101. elasticsearch-cli < "0.4"
  102. eliom = "6.3.0"
  103. eris-lwt
  104. ethernet
  105. ezcurl-lwt
  106. ezirmin
  107. ezjsonm >= "0.4.2" & < "0.5.0"
  108. ezjsonm-lwt
  109. ezresto
  110. ezresto-directory
  111. faraday-lwt
  112. faraday-lwt-unix
  113. fat-filesystem >= "0.12.0"
  114. fiber-lwt
  115. flowtype >= "0.62.0" & < "0.72.0"
  116. frenetic < "2.0.0"
  117. fswatch_lwt
  118. gamepad
  119. gdb
  120. gdbprofiler < "0.3"
  121. git != "1.4.3" & != "1.7.2"
  122. git-paf
  123. git-unix = "1.11.1" | >= "3.0.0" & < "3.10.0"
  124. github
  125. github-hooks
  126. github-unix >= "4.4.0"
  127. gitlab-unix
  128. gluten-lwt < "0.4.0"
  129. gluten-lwt-unix < "0.4.0"
  130. gluten-mirage < "0.4.0"
  131. graphql-lwt
  132. gufo
  133. h2-lwt < "0.10.0"
  134. h2-lwt-unix < "0.10.0"
  135. h2-mirage
  136. happy-eyeballs-lwt
  137. happy-eyeballs-mirage
  138. hardcaml < "1.1.0"
  139. hardcaml-examples >= "0.3.0"
  140. hardcaml-framework
  141. hardcaml-waveterm
  142. hiredis < "0.6"
  143. http-lwt-client
  144. http-multipart-formdata >= "2.0.0" & < "3.0.0"
  145. http2https
  146. httpaf-lwt-unix
  147. hvsock < "1.0.2"
  148. i3ipc
  149. imaplet-lwt
  150. influxdb-lwt
  151. inotify >= "2.4"
  152. inquire < "0.3.0"
  153. iocaml < "0.4.6"
  154. iocaml-kernel >= "0.4.3"
  155. iocamljs-kernel
  156. ip2location
  157. ip2locationio
  158. ipv6-multicast < "0.9"
  159. irc-client-lwt
  160. irc-client-lwt-ssl
  161. irc-client-tls
  162. irmin < "0.9.6" | = "0.9.10" | >= "0.11.0" & < "2.7.0"
  163. irmin-bench < "2.7.0"
  164. irmin-chunk < "2.7.0"
  165. irmin-containers < "2.7.0"
  166. irmin-fs >= "2.3.0" & < "2.7.0"
  167. irmin-git >= "2.3.0" & < "2.7.0"
  168. irmin-graphql >= "2.3.0" & < "2.7.0"
  169. irmin-http >= "2.3.0" & < "2.7.0"
  170. irmin-indexeddb
  171. irmin-layers < "2.7.0"
  172. irmin-mem >= "2.3.0"
  173. irmin-mirage-git >= "2.3.0" & < "2.7.0"
  174. irmin-mirage-graphql >= "2.3.0" & < "2.7.0"
  175. irmin-pack < "2.7.0"
  176. irmin-test >= "2.3.0" & < "2.7.0"
  177. irmin-unix >= "2.3.0" & < "2.7.0"
  178. irmin-watcher
  179. jitsu
  180. joolog
  181. jose < "0.9.0"
  182. js_of_ocaml < "3.0"
  183. js_of_ocaml-lwt
  184. jsoo_broadcastchannel
  185. jsoo_router
  186. jsoo_storage
  187. jupyter < "2.3.0"
  188. jupyter-archimedes < "2.3.2"
  189. jupyter-kernel
  190. KaSim >= "4.0.0"
  191. kafka >= "0.3" & < "0.5"
  192. kafka_lwt
  193. ke >= "0.5"
  194. ketrew >= "3.2.0"
  195. kinetic-client < "0.0.9"
  196. lablqml < "0.6"
  197. lambda-runtime
  198. lambda-term >= "1.11" & < "1.13"
  199. launchd
  200. letsencrypt
  201. letsencrypt-app
  202. letsencrypt-dns
  203. libres3
  204. links < "0.7.3"
  205. lru_cache < "v0.16.0"
  206. lwt-binio
  207. lwt-canceler
  208. lwt-dllist
  209. lwt-exit
  210. lwt-parallel >= "0.1.2"
  211. lwt-pipe
  212. lwt-pipeline
  213. lwt-watcher
  214. lwt-zmq
  215. lwt_camlp4
  216. lwt_domain < "0.3.0"
  217. lwt_eio < "0.4"
  218. lwt_glib >= "1.0.1"
  219. lwt_log < "1.1.0"
  220. lwt_named_threads
  221. lwt_ppx
  222. lwt_ppx_let
  223. lwt_react >= "1.0.1"
  224. lwt_ssl >= "1.0.1"
  225. macaque_lwt
  226. maki
  227. mariadb < "0.5.1"
  228. markup = "0.7.6"
  229. markup-lwt
  230. mdx
  231. mechaml
  232. metrics-influx
  233. metrics-lwt
  234. metrics-mirage
  235. metrics-unix
  236. mindstorm-lwt
  237. mirage < "0.9.1" | >= "0.10.0" & < "2.7.0"
  238. mirage-block < "1.0.0"
  239. mirage-block-ccm
  240. mirage-block-lwt
  241. mirage-block-ramdisk
  242. mirage-block-solo5
  243. mirage-block-unix < "2.8.3"
  244. mirage-block-xen
  245. mirage-bootvar-solo5 >= "0.2.0"
  246. mirage-bootvar-unix
  247. mirage-bootvar-xen >= "0.4.0"
  248. mirage-channel-lwt
  249. mirage-clock-freestanding < "3.0.0"
  250. mirage-clock-lwt
  251. mirage-clock-unix >= "1.2.0" & < "3.0.0"
  252. mirage-console >= "2.1.1" & < "2.2.0"
  253. mirage-console-lwt
  254. mirage-console-solo5 >= "0.2.0"
  255. mirage-console-unix >= "2.2.0" & < "3.0.0"
  256. mirage-console-xen >= "5.0.0"
  257. mirage-console-xen-backend < "3.0.1"
  258. mirage-console-xen-cli
  259. mirage-dns < "3.0.0"
  260. mirage-entropy < "0.5.0"
  261. mirage-entropy-unix
  262. mirage-entropy-xen != "0.2.0"
  263. mirage-flow >= "1.0.3" & < "1.2.0"
  264. mirage-flow-lwt
  265. mirage-flow-rawlink
  266. mirage-flow-unix < "2.0.0"
  267. mirage-fs-lwt
  268. mirage-fs-unix != "1.2.1"
  269. mirage-http
  270. mirage-http-unix
  271. mirage-http-xen
  272. mirage-kv-lwt
  273. mirage-kv-unix
  274. mirage-logs
  275. mirage-nat < "3.0.0"
  276. mirage-net-fd
  277. mirage-net-lwt
  278. mirage-net-macosx
  279. mirage-net-solo5
  280. mirage-net-unix
  281. mirage-net-xen
  282. mirage-os-shim >= "3.0.0"
  283. mirage-profile
  284. mirage-protocols-lwt
  285. mirage-qubes
  286. mirage-qubes-ipv4
  287. mirage-random-stdlib >= "0.1.0"
  288. mirage-solo5
  289. mirage-stack-lwt
  290. mirage-time-lwt
  291. mirage-time-unix < "2.0.0"
  292. mirage-types-lwt < "3.7.1"
  293. mirage-unix
  294. mirage-vnetif
  295. mirage-vnetif-stack
  296. mirage-www >= "1.1.0"
  297. mirage-xen
  298. mirror
  299. mpris = "0.1.1"
  300. mqtt >= "0.0.2"
  301. mrmime >= "0.5.0"
  302. multipart-form-data
  303. multipart_form >= "0.2.0" & < "0.4.0"
  304. multipart_form-lwt
  305. mwt
  306. named-pipe
  307. nanomsg
  308. nbd = "2.1.1" | >= "3.0.0"
  309. nbd-tool
  310. nbd-unix
  311. netchannel
  312. nocrypto >= "0.5.4"
  313. noise
  314. nottui-lwt
  315. nproc
  316. nsq < "0.2.4"
  317. obrowser
  318. obuilder < "0.4"
  319. obus >= "1.1.8" & < "1.2.1"
  320. ocaml-variants >= "4.00.1+mirage-unix" & < "4.00.1+open-types"
  321. ocluster < "0.2"
  322. ocluster-api < "0.2"
  323. ocplib-concur
  324. ocplib-resto
  325. ocsigen-start = "1.1.0" | >= "4.1.0" & < "4.7.0"
  326. ocsigen-toolkit = "1.1.0"
  327. ocsigenserver >= "2.10"
  328. odoc >= "2.0.0" & < "2.1.0"
  329. ojquery
  330. ojs-base < "0.6.0"
  331. opam-compiler < "0.2.0"
  332. opam-publish = "0.3.5"
  333. opam-sync-github-prs
  334. openflow < "0.2.0"
  335. opium >= "0.11.0" & < "0.19.0"
  336. opium_kernel
  337. order-i3-xfce
  338. ordma
  339. osc-lwt
  340. oskel >= "0.3.0"
  341. ounit-lwt < "2.2.0"
  342. ounit2-lwt
  343. ox < "1.1.0"
  344. paf
  345. paf-cohttp
  346. pcap-format >= "0.3.3" & < "0.5.0"
  347. pgx_lwt
  348. pgx_lwt_mirage
  349. pgx_lwt_unix < "2.0"
  350. plotkicadsch < "0.2.0" | >= "0.4.0"
  351. ppx_defer >= "0.4.0"
  352. ppx_deriving_rpc
  353. ppx_json_types
  354. ppx_netblob
  355. ppx_rapper_lwt
  356. ppx_sqlexpr
  357. prof_spacetime
  358. prometheus
  359. prometheus-app
  360. protocol-9p >= "0.10.0"
  361. protocol-9p-unix
  362. pvem_lwt_unix >= "0.0.2"
  363. qcow < "0.11.0"
  364. qcow-format
  365. qcow-tool
  366. qfs >= "0.5" & < "0.7"
  367. quests
  368. rashell
  369. rawlink < "2.1"
  370. rawlink-lwt
  371. redis-lwt
  372. resource-pooling
  373. resp >= "0.10.0"
  374. resp-mirage >= "0.10.0"
  375. resp-unix >= "0.10.0"
  376. resto
  377. resto-cohttp-client
  378. resto-cohttp-self-serving-client
  379. resto-cohttp-server
  380. resto-directory
  381. riak
  382. ringo-lwt
  383. river
  384. rpc >= "1.5.1" & < "7.1.0"
  385. rpclib-js
  386. rpclib-lwt
  387. sanddb >= "0.3.0"
  388. scgi
  389. sendmail-lwt
  390. session-cohttp-lwt
  391. session-cookie-lwt
  392. session-postgresql-lwt < "0.4.1"
  393. sessions
  394. shared-block-ring
  395. shared-memory-ring < "2.0.0"
  396. shared-memory-ring-lwt
  397. skkserv-lite
  398. slacko < "0.14.1"
  399. socket-daemon
  400. spin < "0.6.0"
  401. spotify-web-api < "0.2.1"
  402. sqlexpr
  403. statsd-client
  404. stog >= "0.16.0" & < "0.19.0"
  405. syndic >= "1.4" & < "1.6.0"
  406. tar-format >= "0.4.1"
  407. tar-mirage < "2.2.0"
  408. tar-unix
  409. tcpip >= "3.1.1" & < "4.0.0"
  410. telegraml
  411. testrunner
  412. tezos-p2p >= "11.0" & < "13.0"
  413. tezos-stdlib < "9.0"
  414. tezos-stdlib-unix < "9.0"
  415. tftp
  416. themoviedb
  417. tls >= "0.10.1" & < "0.16.0"
  418. tls-lwt
  419. tls-mirage
  420. tlstunnel >= "0.2.0"
  421. transmission-rpc
  422. tube
  423. tuntap >= "1.0.0" & < "2.0.0"
  424. typerex-lldb
  425. u2f
  426. usb
  427. uspf
  428. uspf-lwt
  429. utop >= "1.4.0"
  430. utp
  431. uwt >= "0.0.2"
  432. vchan >= "0.9.6" & < "2.0.0" | >= "2.0.3"
  433. vchan-unix
  434. vchan-xen
  435. vercel
  436. vhd-format >= "0.6.0" & < "0.9.1"
  437. vhd-format-lwt < "0.12.0"
  438. vhd-tool < "0.12.0"
  439. vmnet
  440. vpnkit >= "0.1.1"
  441. vue-jsoo < "0.3"
  442. webauthn
  443. websocket < "2.3"
  444. websocket-lwt = "2.11"
  445. xe-unikernel-upload
  446. xen-api-client < "0.9.14"
  447. xen-block-driver
  448. xen-evtchn
  449. xen-evtchn-unix
  450. xen-gnt
  451. xenctrl
  452. xenstore
  453. xenstore_transport
  454. xentropyd
  455. yurt != "0.3" & < "0.5"
  456. zbar
  457. zmq-lwt

Conflicts (3)

  1. ocamlbuild = "0.9.0"
  2. ppx_tools < "1.0.0"
  3. ocaml-variants = "4.02.1+BER"