[ANN] shuttle v0.3.1 released


I’d like to announce the release of version 0.3.1 of shuttle.

Installation: opam install shuttle

Shuttle provides an API for buffered I/O for applications using async. It fills the same role as the Reader/Writer modules from async, but only supports file descriptors that support non blocking IO. Feature parity with the reader/writer modules is a non-goal.

The library grew out of experiments in replacing manually orchestrated buffer management in some of my older async based applications. The goal is to have a high level api that gives a similar api as reader/writer modules, while providing a little more control over how/when the writes are scheduled. Credits for the idea go to the Janestreet engineers and their implementation of a low latency transport that’s used in async_rpc.

The initial release consists of:

  1. Shuttle → This is the core library that contains the channel implementation
  2. Shuttle_ssl → Encrypted channels using async_ssl
  3. Shuttle_http → Httpaf driver that uses shuttle instead of httpaf-async. Experimental module mostly used for testing, and some performance benchmarks.

Additional Notes:

  • The httpaf driver has been contributed as a candidate for the http benchmarks maintained by the ocaml-multicore project → Multicore OCaml: September 2021, effect handlers will be in OCaml 5.0!
  • For most use-cases people should still default to the Reader/Writer modules from async_unix. They are battle tested and cover a lot more use-cases.
  • Future work will involve a lot more testing, adding a driver for ocaml-tls, and adding minimal windows support mostly to allow at-least being able to build/develop shuttle based libraries on windows.

There have been some significant changes since this last release (Versions 0.4.0 and 0.5.0 are available on opam):

  • Buffered reader has a new utility method that allows reading lines
  • Shuttle now supports file descriptors that don’t support nonblocking I/O. For blocking I/O Shuttle uses async’s support for running syscalls in its thread pool
  • Buffered reader’s api has been simplified to remove read_one_chunk_at_a_time in favor of a more familiar read, read_line etc. refill operation is supported to perform a read syscall to fill a channel’s buffer, and Input_channel.view can be used to get a view into the channel’s underlying buffer.
  • Supports v0.15 series of the janestreet libraries
  • Buffered reader now uses an auto-growing buffer instead of a fixed size buffer than notified users that the internal buffer is full and no progress can be made unless some content is consumed. This should allow starting with a smaller buffer without needing to worry about implementing some client side buffering to hold unconsumed data. Channels allow configuring an upper bound on the internal buffer length, if a buffer grows beyond that an exception is raised.
  • Buffered writer’s support a richer flush interface. Flush operations report errors encountered while attempting to write any pending bytes. This results in a flush operation that returns a deferred that will resolve at some point with either a success or an error, instead of the older flush operation that would return a deferred that never resolved if there was an error during a write syscall.