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

Conflicts (2)

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

Innovation. Community. Security.