package lwt

  1. Overview
  2. Docs
Promises, concurrency, and parallelized I/O

Install

Dune Dependency

Authors

Maintainers

Sources

3.3.0.tar.gz
sha256=a214b07b89822bb7e0291edbba56e3fb41dbb48b2353e41a7c85c459f832d3eb
md5=47bdf4b429da94419941ebe4354f505f

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: 08 Mar 2018

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 = Lwt_unix.((List.hd addresses).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.


Overview

Lwt compiles to native code on Linux, macOS, Windows, and other systems. It's also routinely compiled to JavaScript for the front end and Node, by js_of_ocaml and BuckleScript.

In Lwt,

  • The core library Lwt provides promises...

  • ...and a few pure-OCaml helpers, such as promise-friendly mutexes, condition variables, and mvars.

  • There is a big Unix binding, Lwt_unix that binds almost every Unix system call. A higher-level module Lwt_io provides nice I/O channels.

  • Lwt_process is for subprocess handling.

  • Lwt_preemptive spawns system threads.

  • The PPX syntax allows using all of the above without going crazy!

  • There are also some other helpers, such as Lwt_react for reactive programming. See the table of contents on the linked manual pages!


Installing

  1. Use your system package manager to install a development libev package. It is 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 nice 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.

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

  • We maintain easy starter issues. These are thoroughly explained and hyperlinked. We hope that this makes working on Lwt accessible even to relative OCaml beginners :)

  • CONTRIBUTING.md contains tips for working on the code, such as how to check the code out, how review works, etc. There is also a high-level outline of the code base.

  • The overall development plan can be found in the roadmap.

  • Ask us anything, whether it's about working on Lwt, or any question at all about it :)

  • The documentation always needs proofreading and fixes.

  • Despite a lot of progress, Lwt still needs more tests.

  • You are welcome to pick up any other issue, review a PR, add your opinion, etc.

  • Any feedback is welcome, including how to make contributing easier!


License

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


Related Libraries

  • alcotest A lightweight framework for unit testing

  • angstrom A library for building parsers with a focus on efficiency, concurrency, and reusability

  • cohttp A lightweight library for writing HTTP clients and servers

  • cstruct A library and syntax extension for interop with C-like structures

  • ezjsonm A library for easy interop with JSON

  • faraday A library for fast and memory-efficient serialization

  • logs A logging library with reporting decoupled from logging

  • lwt-parallel A library for distributed computing

  • opium A web toolkit that uses Sinatra-inspired middleware

Dependencies (7)

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

Conflicts (2)

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

Innovation. Community. Security.