io-classes: Type classes for concurrency with STM, ST and timing

[ apache, control, library ] [ Propose Tags ] [ Report a vulnerability ]

IO Monad class hierarchy compatible with:

packages.

Sublibraries

`io-classes` provides non-standard extensions distributed in public sublibraries

  • io-classes:io-classes - the main library compatible with the above packages

  • io-classes:strict-stm - strict STM API

  • io-classes:strict-mvar - strict MVar API

  • io-classes:si-timers - SI-unit based time / timers API, cancellable timers

  • io-classes:mtl - MTL instances, some of which are experiemental

Documentation

Haddocks of all public sublibraries are published here.


[Skip to Readme]

library io-classes

library io-classes:testlib

Modules

[Index] [Quick Jump]

library io-classes:mtl

library io-classes:si-timers

library io-classes:strict-mvar

Modules

[Index] [Quick Jump]

library io-classes:strict-stm

Flags

Automatic Flags
NameDescriptionDefault
asserts

Enable assertions

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 1.0.0.0, 1.0.0.1, 1.1.0.0, 1.2.0.0, 1.3.0.0, 1.3.1.0, 1.4.0.0, 1.4.1.0, 1.5.0.0, 1.6.0.0, 1.7.0.0
Change log CHANGELOG.md
Dependencies array, async (>=2.1), base (>=4.9 && <4.21), bytestring, deepseq, ghc-internal, io-classes, nothunks, primitive (>=0.7 && <0.11), QuickCheck, stm (>=2.5 && <2.5.2 || >=2.5.3 && <2.6), time (>=1.9.1 && <1.13) [details]
Tested with ghc ==8.10 || ==9.2 || ==9.4 || ==9.6 || ==9.8 || ==9.10
License Apache-2.0[multiple license files]
Copyright 2019-2024 Input Output Global Inc (IOG)
Author Alexander Vieth, Duncan Coutts, Marcin Szamotulski, Thomas Winant
Maintainer Duncan Coutts duncan@well-typed.com, Marcin Szamotulski coot@coot.me
Revised Revision 2 made by IOHK at 2024-08-29T09:14:19Z
Category Control
Bug tracker https://github.com/input-output-hk/io-sim/issues
Source repo head: git clone https://github.com/input-output-hk/io-sim(io-classes)
Uploaded by IOHK at 2024-08-27T18:03:13Z
Distributions NixOS:1.7.0.0
Reverse Dependencies 10 direct, 0 indirect [details]
Downloads 3639 total (174 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2024-08-27 [all 1 reports]

Readme for io-classes-1.7.0.0

[back to package description]

IO Monad Class Hierarchy: io-classes

This package provides a monad class hierarchy which is an interface for both the io-sim and IO monads. It was developed with the following constraints in mind:

  • be a drop-in replacement for IO monad;
  • IO instances do not alter its original semantics, providing a shallow bindings to async, base, stm, and exceptions packages as well as timer API;
  • provide zero-cost abstractions.

We provide also non-standard extensions of this API in sublibraries:

io-classes:strict-stm and nothunks were successfully used in a large code base to eliminate space leaks and keep that property over long development cycles.

Documentation

Hackage doesn't yet support public sublibraries, thus Haddocks are published here.

Support material

Exception Class Hierarchy

This package provides an alternative class hierarchy giving access to exceptions API. The [exception] package class hierarchy is also supported by io-sim, so you can also use either one.

The MonadThrow defined in this package allows working with exceptions without having explicit access to catch or mask. It only provides access to throwIO, bracket, bracket_, and finally. MonadCatch class provides API which allows working with exceptions, e.g. catch or bracketOnError, and MonadMask gives access to low-level mask and friends. This division makes code review process somewhat easier. Using only MonadThrow constraint, the reviewer can be sure that no low-level exception API is used, which usually requires more care. Still MonadThrow is general enough to do resource handling right.

Time and Timer APIs

The time and timer APIs of this package follows closely the API exposed by base and time packages. We separately packaged a more convenient API in [si-timers] (ref SI), which provides a monoidal action of DiffTime on monotonic time as well as exposes 32-bit safe timer API (on 32-bit systems time in microseconds represented as an Int can only hold timeouts of ~35 minutes).

Control.Monad.Class.MonadTimer.NonStandard.MonadTimeout provides a low-level timeout abstraction. On systems that support a native timer manager, it's used to implement its API, which is very efficient even for low-latency timeouts. On other platforms (e.g. Windows), it's good enough for subsecond timeouts but it's not good enough for fine-grained timeouts (e.g. sub milliseconds) as it relays on the GHC thread scheduler. We support MonadTimeout on Linux, MacOS, Windows, and IOSim (and unofficially on GHCJS).

MonadDelay and MonadTimer classes provide a well-established interface to delays & timers.

Software Transactional Memory API

We provide two interfaces to stm API: lazy, included in io-classes; and strict one provided by io-classes:strict-stm.

Threads API

We draw a line between base API and async API. The former is provided by MonadFork the latter by MonadAsync. Both are shallow abstractions around APIs exposed by the base and async packages.

Some other APIs

Differences from base, async, or exceptions packages

Major differences

  • getMonotonicTime returns Time (a newtype wrapper around DiffTime)
  • Deadlock exceptions are not thrown to the main thread (see ref), so they cannot be caught. This was a design decision, which allows to catch all deadlocks which otherwise could be captured by a catch.

Minor differences

Some of the types have more general kind signatures, e.g.

type Async :: (Type -> Type) -> Type -> Type

The first type of kind Type -> Type describes the monad which could be instantiated to IO, IOSim or some other monad stacks built with monad transformers. The same applies to many other types, e.g. TVar, TMVar.

The following types although similar to the originals are not the same as the ones that come from base, async, or exceptions packages:

  • Handler (origin: base)
  • MaskingState (origin: base)
  • Concurrently (origin: async)
  • ExceptionInLinkedThread (origin: async): io-classes version does not store Async
  • ExitCase (origin: exceptions)

Debuging & Insepction

We provide quite extended debugging & inspection API. This proved to be extremely helpful when analysing complex deadlocks or livelocks or writing complex quickcheck properties of a highly concurrent system. Some of this is only possible because we can control the execution environment of io-sim.

  • labelThread as part of MonadThread (IO, io-sim, which is also part of GHC API, ref labelThread);
  • MonadLabelledSTM which allows to label of various STM mutable variables, e.g. TVar, MVar, etc. (io-sim, not provided by GHC);
  • MonadInspectSTM which allows inspecting values of STM mutable variables when they are committed. (io-sim, not provided by GHC).

Monad Transformers

We provide support for monad transformers (although at this stage it might have its limitations and so there might be some rough edges. PRs are welcomed, contributing).