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

Conflicts (3)

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