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. fuseau-lwt
  119. gamepad
  120. gdb
  121. gdbprofiler < "0.3"
  122. git != "1.4.3" & != "1.7.2"
  123. git-paf
  124. git-unix = "1.11.1" | >= "3.0.0" & < "3.10.0"
  125. github
  126. github-hooks
  127. github-unix >= "4.4.0"
  128. gitlab-unix
  129. gluten-lwt < "0.4.0"
  130. gluten-lwt-unix < "0.4.0"
  131. gluten-mirage < "0.4.0"
  132. graphql-lwt
  133. gufo
  134. h2-lwt < "0.10.0"
  135. h2-lwt-unix < "0.10.0"
  136. h2-mirage
  137. happy-eyeballs-lwt
  138. happy-eyeballs-mirage
  139. hardcaml < "1.1.0"
  140. hardcaml-examples >= "0.3.0"
  141. hardcaml-framework
  142. hardcaml-waveterm
  143. hiredis < "0.6"
  144. http-lwt-client
  145. http-multipart-formdata >= "2.0.0" & < "3.0.0"
  146. http2https
  147. httpaf-lwt-unix
  148. hvsock < "1.0.2"
  149. i3ipc
  150. imaplet-lwt
  151. influxdb-lwt
  152. inotify >= "2.4"
  153. inquire < "0.3.0"
  154. iocaml < "0.4.6"
  155. iocaml-kernel >= "0.4.3"
  156. iocamljs-kernel
  157. ip2location
  158. ip2locationio
  159. ipv6-multicast < "0.9"
  160. irc-client-lwt
  161. irc-client-lwt-ssl
  162. irc-client-tls
  163. irmin < "0.9.6" | = "0.9.10" | >= "0.11.0" & < "2.7.0"
  164. irmin-bench < "2.7.0"
  165. irmin-chunk < "2.7.0"
  166. irmin-containers < "2.7.0"
  167. irmin-fs >= "2.3.0" & < "2.7.0"
  168. irmin-git >= "2.3.0" & < "2.7.0"
  169. irmin-graphql >= "2.3.0" & < "2.7.0"
  170. irmin-http >= "2.3.0" & < "2.7.0"
  171. irmin-indexeddb
  172. irmin-layers < "2.7.0"
  173. irmin-mem >= "2.3.0"
  174. irmin-mirage-git >= "2.3.0" & < "2.7.0"
  175. irmin-mirage-graphql >= "2.3.0" & < "2.7.0"
  176. irmin-pack < "2.7.0"
  177. irmin-test >= "2.3.0" & < "2.7.0"
  178. irmin-unix >= "2.3.0" & < "2.7.0"
  179. irmin-watcher
  180. jitsu
  181. joolog
  182. jose < "0.9.0"
  183. js_of_ocaml < "3.0"
  184. js_of_ocaml-lwt
  185. jsoo_broadcastchannel
  186. jsoo_router
  187. jsoo_storage
  188. jupyter < "2.3.0"
  189. jupyter-archimedes < "2.3.2"
  190. jupyter-kernel
  191. KaSim >= "4.0.0"
  192. kafka >= "0.3" & < "0.5"
  193. kafka_lwt
  194. ke >= "0.5"
  195. ketrew >= "3.2.0"
  196. kinetic-client < "0.0.9"
  197. lablqml < "0.6"
  198. lambda-runtime
  199. lambda-term >= "1.11" & < "1.13"
  200. launchd
  201. letsencrypt
  202. letsencrypt-app
  203. letsencrypt-dns
  204. libres3
  205. links < "0.7.3"
  206. lru_cache < "v0.16.0"
  207. lwt-binio
  208. lwt-canceler
  209. lwt-dllist
  210. lwt-exit
  211. lwt-parallel >= "0.1.2"
  212. lwt-pipe
  213. lwt-pipeline
  214. lwt-watcher
  215. lwt-zmq
  216. lwt_camlp4
  217. lwt_domain < "0.3.0"
  218. lwt_eio < "0.4"
  219. lwt_glib >= "1.0.1"
  220. lwt_log < "1.1.0"
  221. lwt_named_threads
  222. lwt_ppx
  223. lwt_ppx_let
  224. lwt_react >= "1.0.1"
  225. lwt_ssl >= "1.0.1"
  226. macaque_lwt
  227. maki
  228. mariadb < "0.5.1"
  229. markup = "0.7.6"
  230. markup-lwt
  231. mdx
  232. mechaml
  233. metrics-influx
  234. metrics-lwt
  235. metrics-mirage
  236. metrics-unix
  237. mindstorm-lwt
  238. mirage < "0.9.1" | >= "0.10.0" & < "2.7.0"
  239. mirage-block < "1.0.0"
  240. mirage-block-ccm
  241. mirage-block-lwt
  242. mirage-block-ramdisk
  243. mirage-block-solo5
  244. mirage-block-unix < "2.8.3"
  245. mirage-block-xen
  246. mirage-bootvar-solo5 >= "0.2.0"
  247. mirage-bootvar-unix
  248. mirage-bootvar-xen >= "0.4.0"
  249. mirage-channel-lwt
  250. mirage-clock-freestanding < "3.0.0"
  251. mirage-clock-lwt
  252. mirage-clock-unix >= "1.2.0" & < "3.0.0"
  253. mirage-console >= "2.1.1" & < "2.2.0"
  254. mirage-console-lwt
  255. mirage-console-solo5 >= "0.2.0"
  256. mirage-console-unix >= "2.2.0" & < "3.0.0"
  257. mirage-console-xen >= "5.0.0"
  258. mirage-console-xen-backend < "3.0.1"
  259. mirage-console-xen-cli
  260. mirage-dns < "3.0.0"
  261. mirage-entropy < "0.5.0"
  262. mirage-entropy-unix
  263. mirage-entropy-xen != "0.2.0"
  264. mirage-flow >= "1.0.3" & < "1.2.0"
  265. mirage-flow-lwt
  266. mirage-flow-rawlink
  267. mirage-flow-unix < "2.0.0"
  268. mirage-fs-lwt
  269. mirage-fs-unix != "1.2.1"
  270. mirage-http
  271. mirage-http-unix
  272. mirage-http-xen
  273. mirage-kv-lwt
  274. mirage-kv-unix
  275. mirage-logs
  276. mirage-nat < "3.0.0"
  277. mirage-net-fd
  278. mirage-net-lwt
  279. mirage-net-macosx
  280. mirage-net-solo5
  281. mirage-net-unix
  282. mirage-net-xen
  283. mirage-os-shim >= "3.0.0"
  284. mirage-profile
  285. mirage-protocols-lwt
  286. mirage-qubes
  287. mirage-qubes-ipv4
  288. mirage-random-stdlib >= "0.1.0"
  289. mirage-solo5
  290. mirage-stack-lwt
  291. mirage-time-lwt
  292. mirage-time-unix < "2.0.0"
  293. mirage-types-lwt < "3.7.1"
  294. mirage-unix
  295. mirage-vnetif
  296. mirage-vnetif-stack
  297. mirage-www >= "1.1.0"
  298. mirage-xen
  299. mirror
  300. mpris = "0.1.1"
  301. mqtt >= "0.0.2"
  302. mrmime >= "0.5.0"
  303. multipart-form-data
  304. multipart_form >= "0.2.0" & < "0.4.0"
  305. multipart_form-lwt
  306. mwt
  307. named-pipe
  308. nanomsg
  309. nbd = "2.1.1" | >= "3.0.0"
  310. nbd-tool
  311. nbd-unix
  312. netchannel
  313. nocrypto >= "0.5.4"
  314. noise
  315. nottui-lwt
  316. nproc
  317. nsq < "0.2.4"
  318. obrowser
  319. obuilder < "0.4"
  320. obus >= "1.1.8" & < "1.2.1"
  321. ocaml-variants >= "4.00.1+mirage-unix" & < "4.00.1+open-types"
  322. ocluster < "0.2"
  323. ocluster-api < "0.2"
  324. ocplib-concur
  325. ocplib-resto
  326. ocsigen-start = "1.1.0" | >= "4.1.0" & < "4.7.0"
  327. ocsigen-toolkit = "1.1.0"
  328. ocsigenserver >= "2.10"
  329. odoc >= "2.0.0" & < "2.1.0"
  330. ojquery
  331. ojs-base < "0.6.0"
  332. opam-compiler < "0.2.0"
  333. opam-publish = "0.3.5"
  334. opam-sync-github-prs
  335. openflow < "0.2.0"
  336. opium >= "0.11.0" & < "0.19.0"
  337. opium_kernel
  338. order-i3-xfce
  339. ordma
  340. osc-lwt
  341. oskel >= "0.3.0"
  342. ounit-lwt < "2.2.0"
  343. ounit2-lwt
  344. ox < "1.1.0"
  345. paf
  346. paf-cohttp
  347. pcap-format >= "0.3.3" & < "0.5.0"
  348. pgx_lwt
  349. pgx_lwt_mirage
  350. pgx_lwt_unix < "2.0"
  351. plotkicadsch < "0.2.0" | >= "0.4.0"
  352. ppx_defer >= "0.4.0"
  353. ppx_deriving_rpc
  354. ppx_json_types
  355. ppx_netblob
  356. ppx_rapper_lwt
  357. ppx_sqlexpr
  358. prof_spacetime
  359. prometheus
  360. prometheus-app
  361. promise_jsoo_lwt
  362. protocol-9p >= "0.10.0"
  363. protocol-9p-unix
  364. pvem_lwt_unix >= "0.0.2"
  365. qcow < "0.11.0"
  366. qcow-format
  367. qcow-tool
  368. qfs >= "0.5" & < "0.7"
  369. quests
  370. rashell
  371. rawlink < "2.1"
  372. rawlink-lwt
  373. redis-lwt
  374. resource-pooling
  375. resp >= "0.10.0"
  376. resp-mirage >= "0.10.0"
  377. resp-unix >= "0.10.0"
  378. resto
  379. resto-cohttp-client
  380. resto-cohttp-self-serving-client
  381. resto-cohttp-server
  382. resto-directory
  383. riak
  384. ringo-lwt
  385. river
  386. rpc >= "1.5.1" & < "7.1.0"
  387. rpclib-js
  388. rpclib-lwt
  389. sanddb >= "0.3.0"
  390. scgi
  391. sendmail-lwt
  392. session-cohttp-lwt
  393. session-cookie-lwt
  394. session-postgresql-lwt < "0.4.1"
  395. sessions
  396. shared-block-ring
  397. shared-memory-ring < "2.0.0"
  398. shared-memory-ring-lwt
  399. skkserv-lite
  400. slacko < "0.14.1"
  401. socket-daemon
  402. spin < "0.6.0"
  403. spotify-web-api < "0.2.1"
  404. sqlexpr
  405. statsd-client
  406. stog >= "0.16.0" & < "0.19.0"
  407. syndic >= "1.4" & < "1.6.0"
  408. tar-format >= "0.4.1"
  409. tar-mirage < "2.2.0"
  410. tar-unix
  411. tcpip >= "3.1.1" & < "4.0.0"
  412. telegraml
  413. testrunner
  414. tezos-p2p >= "11.0" & < "13.0"
  415. tezos-stdlib < "9.0"
  416. tezos-stdlib-unix < "9.0"
  417. tftp
  418. themoviedb
  419. tls >= "0.10.1" & < "0.16.0"
  420. tls-lwt
  421. tls-mirage
  422. tlstunnel >= "0.2.0"
  423. transmission-rpc
  424. tube
  425. tuntap >= "1.0.0" & < "2.0.0"
  426. typerex-lldb
  427. u2f
  428. usb
  429. uspf
  430. uspf-lwt
  431. utop >= "1.4.0"
  432. utp
  433. uwt >= "0.0.2"
  434. vchan >= "0.9.6" & < "2.0.0" | >= "2.0.3"
  435. vchan-unix
  436. vchan-xen
  437. vercel
  438. vhd-format >= "0.6.0" & < "0.9.1"
  439. vhd-format-lwt < "0.12.0"
  440. vhd-tool < "0.12.0"
  441. vmnet
  442. vpnkit >= "0.1.1"
  443. vue-jsoo < "0.3"
  444. webauthn
  445. websocket < "2.3"
  446. websocket-lwt = "2.11"
  447. xe-unikernel-upload
  448. xen-api-client < "0.9.14"
  449. xen-block-driver
  450. xen-evtchn
  451. xen-evtchn-unix
  452. xen-gnt
  453. xenctrl
  454. xenstore
  455. xenstore_transport
  456. xentropyd
  457. yurt != "0.3" & < "0.5"
  458. zbar
  459. zmq-lwt

Conflicts (3)

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