Eio provides an effects-based direct-style IO stack for OCaml 5.0. It aims to be easy to use, secure, well documented, and fast. It consists of a generic cross-platform API, plus optimised backends for different platforms. It can be used instead of (or alongside) Lwt and Async.
Recent changes
There have been several releases since the last announcement here. The bigger changes include:
- Fiber-local storage (thanks to Jonathan Coates). This allows e.g. a web-server to attach a request ID to the fiber that is handling it, and then display this in all log messages generated by that request.
- Eio.Mutex and Eio.Condition (@Lortex). These are similar to the ones in the standard library, but they allow other fibers to run while waiting instead of blocking the whole domain.
- Eio.Buf_write is a port of Faraday to Eio, allowing efficient output buffering.
- Fiber.fork_daemon allows spawning a fiber that will be cancelled automatically when the non-daemon fibers have finished. This is useful for e.g. running a thread to collect entropy for a random number generator while a program is running, without it preventing the program from finishing.
-
Fiber.{iter,map,filter,fiter_map} provide concurrent versions of the corresponding operations in
List
. -
Eio.Path provides file-system access. New operations include
read_dir
(@patricoferris),unlink
,rmdir
andrename
. - The networking APIs now include UDP (@patricoferris) and DNS (@bikalgurung), and IPv6 now works (@haesbaert).
-
Eio_mock provides a framework for creating mocks for testing, along with pre-defined ones for flows and networks.
Eio_mock.Backend
is a special backend for tests. It does no real IO, but can report if your tests deadlock. - The much-requested Eio_unix.sleep is now available as a direct replacement for
Lwt_unix.sleep
.
See the release notes for full details, and the tutorial for an introduction.
Integration with Lwt and Async
Lwt_eio allows running Lwt and Eio code together in a single domain. The 0.2 release adds support for integrating Lwt and Eio cancellation. The porting guide shows how to update an Lwt application to Eio incrementally.
Async_eio allows running Async and Eio code together in a single domain. This is experimental and requires some changes to Async itself.
async-eio-lwt-chimera shows how Async, Eio and Lwt code can all be used together in a single event loop. It runs an Async server that handles connections using an Lwt handler that reads a line from the request and then handles it by using Eio to read the named file from its data directory.
Porting
It’s useful for people to try porting applications and libraries to Eio so we can get feedback on the APIs and prioritise missing features. The Lwt and Async porting guides linked above may be helpful. Some examples so far include:
- ocaml-cohttp (@bikalgurung)
- ocaml-geojson (@patricoferris)
- capnp-rpc (@talex5)
- rawlink (@haesbaert)
- dream (@talex5)
- mirage (@Lortex)
- mirage-crypto (@BikalGurung)
- ocaml-dns (@BikalGurung)
- ocaml-ci-web (@talex5)
- gluten (@anmonteiro)
Backends
The recent uring releases have brought improved performance and several new features to the eio_linux
backend.
We are still hoping to persuade a Windows user to try using Eio. The Luv backend should mostly work, but there are likely some problems with paths, etc. Even better would be if someone writes a dedicated eio_windows
backend.
To add a backend for a new platform, it is best to start by studying Eio_mock.Backend, which is very simple as it does no IO. To add IO, you can copy the pattern in either eio_linux
(which provides its own event loop that asks the OS to sleep) or the one in eio_luv
(which delegates to an event loop provided by another library).