Although we try to contain the use of IO at the outskirt of the Hydra node using Handle pattern and Reactive core, low-level effects are still needed in various places, notably to define concurrently executing actions, and thus need to be tested
Testing asynchronous and concurrent code is notoriously painful
The ouroboros consensus test suite and hydra-sim simulation have demonstrated the effectiveness of abstracting concurrent primitives through the use of typeclasses (MTL-style pattern) and being able to run these as pure code, harvesting and analysing produced execution traces.
There are other such libraries, e.g. concurrency and dejafu, as well as the venerable exceptions (for abstracting exception throwing).
For all IO effects covered by the library, use functions from typeclasses exposed by io-classes. As of this writing, this covers:
- All STM operations through
- Time and timers through
- Concurrency through
- Exceptions through
We can use
io-sim to evaluate IO-ish functions easily
Instantiation to concrete IO is pushed at the outermost layer, eg. in the
Main or tests.
As some of these functions and typeclasses clash with the
cardano-prelude we might
want to define a custom prelude (candidate for another ADR)