Skip to content

Commit

Permalink
Include strict-stm, strict-mvar and si-timers into io-classes
Browse files Browse the repository at this point in the history
`strict-mvar:test` is left in `test-strict-mvar` as it introduces
a cycle between `io-sim` and `io-classes` which cabal cannot resolve.
  • Loading branch information
coot committed Aug 26, 2024
1 parent 29daad4 commit 9bbca2e
Show file tree
Hide file tree
Showing 43 changed files with 204 additions and 747 deletions.
14 changes: 0 additions & 14 deletions .github/workflows/cabal.project.local
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,6 @@ package io-classes
ghc-options: -Werror
flags: +asserts

package io-classes-mtl
ghc-options: -Werror

package strict-mvar
ghc-options: -Werror

package strict-stm
ghc-options: -Werror
flags: +asserts

package io-sim
ghc-options: -Werror
flags: +asserts

package si-timers
ghc-options: -Werror
flags: +asserts
12 changes: 7 additions & 5 deletions .github/workflows/haskell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ jobs:

- name: Build dependencies
run: |
cabal build --only-dependencies all
cabal build --only-dependencies io-classes
cabal build --only-dependencies io-sim
cabal build --only-dependencies test-strict-mvar
- uses: actions/cache/save@v4
name: "Save cabal store"
Expand All @@ -103,8 +105,8 @@ jobs:
- name: io-sim [test]
run: cabal run io-sim:test

- name: si-timers [test]
run: cabal run si-timers:test
- name: io-classes:si-timers [test]
run: cabal run io-classes:test-si-timers

- name: strict-mvar [test]
run: cabal run strict-mvar:test
- name: test-strict-mvar [test]
run: cabal run test-strict-mvar
44 changes: 23 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@
* tracing committed changes to `TVar`, `TMVar`s, etc.
* labeling of threads, `TVar`'s, etc.

[`io-classes`] provides an interface, which allows writing code that can be run
in both real `IO` and [`IOSim`]. It is a drop-in replacement for `IO`, and
supports interfaces commonly known from `base`, `exceptions`, `stm`, `async`,
or `time` packages.

One of the principles of `io-classes` was to stay as close to `IO` as possible,
thus most of the `IO` instances are directly referring to `base` or `async`
API. However, we made some distinctions, which are reported below.

[`io-classes`] supports a novel hierarchy for error-handling monads as well as
more familiar `exception` style. The new hierarchy provides `bracket` and
`finally` functions in the `MonadThrow` class, while `catch` style operators
are provided by a super-class `MonadCatch`. Both `bracket` and `finally` are
the most common functions used to write code with robust exception handling,
exposing them through the more basic `MonadThrow` class informs the reader
/ reviewer that no tricky error handling is done in that section of the code
base.
[`io-classes:io-classes`] provides an interface, which allows writing code that
can be run in both real `IO` and [`IOSim`]. It is a drop-in replacement for
`IO`, and supports interfaces commonly known from `base`, `exceptions`, `stm`,
`async`, or `time` packages.

One of the principles of `io-classes:io-classes` was to stay as close to `IO`
as possible, thus most of the `IO` instances are directly referring to `base`
or `async` API. However, we made some distinctions, which are reported below.

[`io-classes:io-classes`] supports a novel hierarchy for error-handling monads
as well as more familiar `exception` style. The new hierarchy provides
`bracket` and `finally` functions in the `MonadThrow` class, while `catch`
style operators are provided by a super-class `MonadCatch`. Both `bracket` and
`finally` are the most common functions used to write code with robust
exception handling, exposing them through the more basic `MonadThrow` class
informs the reader / reviewer that no tricky error handling is done in that
section of the code base.

[`IOSim`] exposes a detailed trace, which can be enhanced by labeling threads, or
mutable variables, tracing `Dynamic` values (which can be recovered from the
Expand All @@ -58,16 +58,18 @@ a complex, highly concurrent, distributed system
* [`io-sim`]: provides two simulator interpreters: [`IOSim`] and
`IOSimPOR` - an enhanced [`IOSim`] version with schedule discovery
capabilities.
* [`io-classes`]: class bases interface, which allows to to abstract over the
* [`io-classes:io-classes`]: class bases interface, which allows to to abstract over the
monad
* [`strict-stm`]: strict STM operations
* [`si-timers`]: non-standard timers API
* [`io-classes:strict-stm`]: strict STM operations
* [`io-classes:si-timers`]: non-standard timers API

### Issues

New issues should be reported in [this][io-sim-issues] repository.

[`io-classes`]: https://hackage.haskell.org/package/io-classes
[`io-classes:io-classes`]: https://hackage.haskell.org/package/io-classes
[`io-classes:strict-stm`]: https://hackage.haskell.org/package/io-classes
[`io-classes:si-timers`]: https://hackage.haskell.org/package/io-classes
[`io-sim`]: https://hackage.haskell.org/package/io-sim

[contra-tracer]: https://hackage.haskell.org/package/contra-tracer
Expand Down
4 changes: 1 addition & 3 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ index-state: hackage.haskell.org 2024-05-17T03:42:00Z
packages: ./io-sim
./io-classes
./io-classes-mtl
./strict-mvar
./strict-stm
./si-timers
./test-strict-mvar

package io-sim
flags: +asserts
Expand Down
3 changes: 1 addition & 2 deletions io-classes-mtl/io-classes-mtl.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ library
array,
mtl,

io-classes ^>=1.5,
si-timers,
io-classes:{io-classes,si-timers} ^>= 1.5


hs-source-dirs: src
Expand Down
19 changes: 19 additions & 0 deletions io-classes/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Revsion history of io-classes

### Next version

### Breaking changes

* `strict-stm`, `strict-mvar` and `si-timers` are now public sublibraries of `io-classes` package.

## 1.5.0.0

### Breaking changes
Expand All @@ -12,6 +18,19 @@

* Add `writeTMVar` to `MonadSTM`.

* `strict-stm`, `strict-mvar` and `si-timers` were moved to `io-classes` as
**public sublibraries**. You can import then in `*.cabal` files with the
following syntax `io-classes:strict-stm` or `io-classes:{strict-stm,
si-timers}`. See the _Multiple public libraries_ subsection of [_Internal
Libraries_][sublibs] section in the `cabal` documentation.

Note: some time in the future we will deprecate `Hackage` packages
`strict-stm`, `strict-mvar` and `si-timers`. If one will want to use the
namespace for a non `io-classes` related packages please contact the
maintainer.

[sublibs]: https://cabal.readthedocs.io/en/stable/cabal-package.html#sublibs

## 1.4.1.0

### Non-breaking changes
Expand Down
30 changes: 18 additions & 12 deletions io-classes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ constraints in mind:
as timer API;
* provide zero-cost abstractions.

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

* [`strict-stm`]: strict `TVar`'s, and other mutable `STM` variables, with
* [`io-classes:strict-stm`]: strict `TVar`'s, and other mutable `STM` variables, with
support of the [`nothunks`] library;
* [`si-timers`]: timers api:
* [`io-classes:strict-mvar`]: strict `MVar`s
* [`io-classes:si-timers`]: timers api:
- 32-bit safe API using `DiffTime` measured in seconds (rather than time in
microseconds represented as `Int` as in `base`)
- cancellable timeouts.
* [`io-classes-mtl`]: MTL instances.

[`strict-stm`] and [`nothunks`] were successfully used in a large code base to
eliminate space leaks and keep that property over long development cycles.
[`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.

## Exception Class Hierarchy

Expand Down Expand Up @@ -61,15 +64,14 @@ delays & timers.
## Software Transactional Memory API

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

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](https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadFork.html#t:MonadFork)
the latter by
[MonadAsync](https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadFork.html#t:MonadAsync).
[MonadAsync](https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadAsync.html#t:MonadAsync).
Both are shallow abstractions around APIs exposed by the `base` and `async`
packages.

Expand Down Expand Up @@ -140,17 +142,21 @@ its limitations and so there might be some rough edges. PRs are welcomed,
[`base`]: https://hackage.haskell.org/package/base
[`exceptions`]: https://hackage.haskell.org/package/exceptions
[`io-sim`]: https://hackage.haskell.org/package/io-sim
[`si-timers`]: https://hackage.haskell.org/package/si-timers
[`io-classes-mtl`]: https://hackage.haskell.org/package/io-classes-mtl
[`stm`]: https://hackage.haskell.org/package/stm
[`strict-stm`]: https://hackage.haskell.org/package/strict-stm
[`threadDelay`]: https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadTimer.html#v:threadDela
[`threadDelay`]: https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadTimer.html#v:threadDelay
[`time`]: https://hackage.haskell.org/package/time
[contributing]: https://www.github.com/input-output-hk/io-sim/tree/master/CONTRIBUTING.md
[`nothunks`]: https://hackage.haskell.org/package/nothunks
[labelThread-base]: https://hackage.haskell.org/package/base-4.17.0.0/docs/GHC-Conc-Sync.html#v:labelThread
[io-deadlock]: https://hackage.haskell.org/package/base-4.19.0.0/docs/Control-Exception.html#t:Deadlock

[MonadEventlog]: https://hackage.haskell.org/package/io-sim-classes/docs/Control-Monad-Class-MonadEventlog.html#t:MonadEventlog
<!-- these links need to be updated once haskell/hackage-server#1218 is done --!>
[`io-classes:si-timers`]: https://hackage.haskell.org/package/io-classes
[`io-classes:strict-stm`]: https://hackage.haskell.org/package/io-classes
[`io-classes:strict-mvar`]: https://hackage.haskell.org/package/io-classes

[MonadEventlog]: https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadEventlog.html#t:MonadEventlog
[Debug.Trace]: https://hackage.haskell.org/package/base/docs/Debug-Trace.html
[MonadST]: https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadST.html#t:MonadST
[MonadSay]: https://hackage.haskell.org/package/io-classes/docs/Control-Monad-Class-MonadSay.html#t:MonadSay
97 changes: 96 additions & 1 deletion io-classes/io-classes.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ author: Alexander Vieth, Duncan Coutts, Marcin Szamotulski, Thomas
maintainer: Duncan Coutts [email protected], Marcin Szamotulski [email protected]
category: Control
build-type: Simple
extra-doc-files: CHANGELOG.md README.md
extra-doc-files: CHANGELOG.md README.md strict-stm/README.md strict-mvar/README.md
bug-reports: https://github.com/input-output-hk/io-sim/issues
tested-with: GHC == { 8.10, 9.2, 9.4, 9.6, 9.8, 9.10 }

Expand Down Expand Up @@ -106,3 +106,98 @@ library

if flag(asserts)
ghc-options: -fno-ignore-asserts

library strict-stm
visibility: public
hs-source-dirs: strict-stm

exposed-modules: Control.Concurrent.Class.MonadSTM.Strict
Control.Concurrent.Class.MonadSTM.Strict.TArray
Control.Concurrent.Class.MonadSTM.Strict.TBQueue
Control.Concurrent.Class.MonadSTM.Strict.TChan
Control.Concurrent.Class.MonadSTM.Strict.TMVar
Control.Concurrent.Class.MonadSTM.Strict.TQueue
Control.Concurrent.Class.MonadSTM.Strict.TVar
reexported-modules: Control.Concurrent.Class.MonadSTM.TSem as Control.Concurrent.Class.MonadSTM.Strict.TSem
default-language: Haskell2010
default-extensions: ImportQualifiedPost
build-depends: base >= 4.9 && <4.21,
array,
stm >= 2.5 && <2.6,

io-classes:io-classes,
ghc-options: -Wall
-Wno-unticked-promoted-constructors
-Wcompat
-Wincomplete-uni-patterns
-Wincomplete-record-updates
-Wpartial-fields
-Widentities

if flag(asserts)
ghc-options: -fno-ignore-asserts

library strict-mvar
visibility: public
hs-source-dirs: strict-mvar/src

exposed-modules: Control.Concurrent.Class.MonadMVar.Strict
default-language: Haskell2010
default-extensions: ImportQualifiedPost
build-depends: base >= 4.9 && <4.21,
io-classes:io-classes,
ghc-options: -Wall
-Wno-unticked-promoted-constructors
-Wcompat
-Wincomplete-uni-patterns
-Wincomplete-record-updates
-Wpartial-fields
-Widentities

library si-timers
import: warnings
visibility: public
hs-source-dirs: si-timers/src
exposed-modules: Control.Monad.Class.MonadTime.SI
Control.Monad.Class.MonadTimer.SI
other-modules: Control.Monad.Class.MonadTimer.NonStandard
default-language: Haskell2010
default-extensions: ImportQualifiedPost
other-extensions: BangPatterns,
CPP,
ConstraintKinds,
DefaultSignatures,
DeriveGeneric,
NumericUnderscores,
ScopedTypeVariables,
TypeFamilies
build-depends: base >=4.9 && <4.21,
deepseq,
mtl,
nothunks,
stm,
time >=1.9.1 && <1.13,

io-classes:io-classes
^>=1.5
if flag(asserts)
ghc-options: -fno-ignore-asserts

-- Since `io-sim` depends on `si-times` (`io-sim` depends on `Time`) some tests of
-- are in `io-sim:test`: this is a good enough reason to pull `io-sim:test`
-- into a seprate package.
test-suite test-si-timers
import: warnings
type: exitcode-stdio-1.0
hs-source-dirs: si-timers/test
main-is: Main.hs
other-modules: Test.MonadTimer
default-language: Haskell2010
default-extensions: ImportQualifiedPost
build-depends: base,

QuickCheck,
tasty,
tasty-quickcheck,

si-timers
21 changes: 21 additions & 0 deletions io-classes/si-timers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# [SI] Timers

The `io-classes:si-timers` package provides delays & timeouts which are safe on
32-bit systems; cancellable timeouts (see `registerDelayCancellable`);
a refined interface for monotonic `Time`. `Time` is given with left monoid
action of `DiffTime` (which encodes the notion of time differences). The
`MonadMonotonicTime`, `MonadDelay` type classes & `MonadTimers` (type synonym)
API provide a consistent interface for working with delays and timeouts.

`io-classes:si-timers` package also defined a low level `MonadTimout` type
class. On system with a native timer manager (e.g. `Linux`, `MacOS`,
`FreeBSD`), it's very efficient but for other platforms (e.g. `Windows`), it
might not be the right API for low latency timeouts needed for example for low
level networking code, because it relies on `GHC`'s `RTS` thread scheduling.

`io-classes:si-timers` are compatible with `io-sim`.

The `SI` comes from the [International System of Units][SI].

[SI]: https://www.wikiwand.com/en/International_System_of_Units
[`io-sim`]: https://hackage.haskell.org/package/io-sim
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions io-classes/strict-mvar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Strict Mutable Variables

The `io-classes:strict-mvar` package provides a strict interface to mutable
variables (`MVar`). It builds on top of `io-classes:io-classes`, and thus it
provides the interface for `MVar`s implementations from both
[base](https://hackage.haskell.org/package/base-4.17.0.0/docs/Control-Concurrent-MVar.html)
and [io-sim](https://github.com/input-output-hk/io-sim).
6 changes: 3 additions & 3 deletions strict-stm/README.md → io-classes/strict-stm/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Strict Software Transaction Memory

The `strict-stm` package provides a strict interface to software transaction
memory. It builds on top of [`io-classes`] and thus it provides the interface
The `io-classes:strict-stm` package provides a strict interface to software transaction
memory. It builds on top of [`io-classes:io-classes`] and thus it provides the interface
for both [`stm`] as well as [`io-sim`].

# Novel testing / space-leak elimination approach
Expand All @@ -12,7 +12,7 @@ which might lurk in `stm` shared mutable variables. Together with the
system ([`cardano-node`]) space leak free.

[`cardano-node`]: https://www.github.com/input-output-hk/cardano-node
[`io-classes`]: https://hackage.haskell.org/package/io-classes
[`io-classes:io-classes`]: https://hackage.haskell.org/package/io-classes
[`io-sim`]: https://hackage.haskell.org/package/io-sim
[`nothunks`]: https://hackage.haskell.org/package/nothunks
[`stm`]: https://hackage.haskell.org/package/stm
Loading

0 comments on commit 9bbca2e

Please sign in to comment.