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

Conflicts (2)

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

Innovation. Community. Security.