package lwt

  1. Overview
  2. Docs
Concurrency based on promises

Install

Dune Dependency

Authors

Maintainers

Sources

3.1.0.tar.gz
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

  1. Use your system package manager to install a development libev package, often called libev-dev or libev-devel.

  2. 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)

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

Conflicts (2)

  1. dune >= "1.7.0"
  2. ocaml-variants = "4.02.1+BER"
OCaml

Innovation. Community. Security.