Version 4 (modified by simonmar, 3 years ago)

--

Async package proposal

This is a proposal for the 'async' package to be included in the next major release of the Haskell platform.

Everyone is invited to review this proposal, following the standard procedure for proposing and reviewing packages.

Reviewers may want to first read the previous thread on the libraries list: http://www.haskell.org/pipermail/libraries/2012-June/017892.html. The current API in async-2.0.0.0 was the result of this discussion.

Review comments should be sent to the libraries mailing list by 13 July 2012 so that we have time to discuss and resolve issues before the final deadline on 13 August 2012.

Credits

Proposal author and package maintainer: Simon Marlow <marlowsd@gmail.com>

The following individuals contributed to the review process:

  • ...

Abstract

The async package provides a higher-level interface over threads, in which an Async a is a concurrent thread that will eventually deliver a value of type a. The package provides ways to create Async computations, wait for their results, and cancel them.

Using Async is safer than using threads in two ways:

  • When waiting for a thread to return a result, if the thread dies with an exception then the caller must either re-throw the exception (wait) or handle it (waitCatch); the exception cannot be ignored.
  • The API makes it possible to build a tree of threads that are automatically killed when their parent dies (see withAsync).

Documentation and tarball from the hackage page:

http://hackage.haskell.org/package/async

Github page:

https://github.com/simonmar/async

Rationale

This API helps in three ways:

  • by packaging up some functionality that is often reimplemented;
  • by avoiding some common mistakes (see the Abstract above);
  • and by providing optimised implementations of the abstractions.

Introduction to the API

See the Haddock documentation: http://community.haskell.org/~simonmar/async/Control-Concurrent-Async.html

Design decisions

The implementation is based on STM, because that enables waitAny and waitBoth to be implemented very straightforwardly. Without STM these operations would require extra threads, and would be hard to get right. Using STM also means that users can compose async operations with their own STM operations.

The concurrently, race, and race_ functions are implemented using threads and MVar for performance (there is a commented-out STM version in the code and documentation to give the semantics). The benchmark demonstrating the difference is in bench/race.hs; it runs about 30% faster with the MVar version.

Should cancel be synchronous or asynchronous? (I addressed this here).

Open issues

  • Perhaps there is a better name for waitCatch and friends?
  • Is there a better name for tryWait? (current name is by analogy with tryTakeMVar)
  • What should waitAny return?
  • Perhaps waitAny should work on any Foldable?