Be notified of new releases
Create your free GitHub account today to subscribe to this repository for new releases and build software alongside 28 million developers.Sign up
bhead is not a functionFFI errors when yielding a fork at the tail of a fresh attempt context (possibly through
This release (v4.0.0) features a revamped API for writing more expressive asynchronous programs with stronger guarantees.
Fibercooperative multi-tasking primitive for fork/join workflows.
- Stronger cleanup guarantees with
- Rewritten core with an emphasis on performance and consistency.
New Features and Enhancements
forkAff, but it was very difficult to get values back when forked computations completed. Libraries like
purescript-aff-future were written to overcome this limitation (though with limitations of their own). The semantics of
purescript-aff-future have been assimilated into
Aff through the
Fiber type without any of the previous limitaions (like lack of cancellation).
Fibers make it easy to not only fork computations, but also share their results among many consumers with
joinFiber, which will wait until the
Fiber completes, or yield immediately if it has already resolved. If a
Fiber threw an exception, then the exception will be rethrown in the observer.
Fibers additionally support cancellation (
killFiber) and finalizers for cleanup (
When we kill/cancel a
Fiber, often times we need to make sure some resource gets released.
bracket lets you take control of the acquire/use/release resource cycle.
example = bracket (openFile myFile) -- Acquire a resource (\file -> closeFile file) -- Release the resource (\file -> appendFile "hello" file) -- Use the resource
In the example above, the runtime will always ensure the "release" effect will run even in the presence of cancellation. There is also
generalBracket, which lets you observe whether the primary action completed successfully, threw an exception, or was killed asynchronously and run different cleanup effects accordingly.
Sometimes we need to fork many
Fibers for a task, but it's possible (often through cancellation) for these sub-tasks to leak. We've introduced a
supervise combinator which will automatically keep track of forked
Fibers and clean them up and run their finalizers once the computation completes or is cancelled.
example = supervise do _ <- forkAff requestA _ <- forkAff requestB requestC
In the above example, if
requestB are still running when
requestC completes, they will be killed by the runtime and have their finalizers run.
As an alternative to
forkAff, which eagerly forks and runs a computations, we've introduced
suspendAff. This forks a computation but does not initiate it until a result is demanded via
joinFiber. Results are still memoized (as all
Fiber results are), but are just computed lazily.
With the old callback approach, each bind resulted in more and more stack, and it was trivial to blow the stack unless you explicitly used
Aff interpreter now uses a constant amount of stack space, making
tailRecM unnecesary. This extends to
ParAff as well.
Previously, exceptions thrown in forked computations were completely swallowed. This made it extremely difficult to diagnose bugs. Now if a
Fiber has no observers and it throws an exception, the exception will always be rethrown in a fresh stack. This can be observed by things like
window.onerror or just by watching the console.
- The low-level callback representation is no longer relevant. If you've defined
Affeffects via the FFI, you should transition to using
Control.Monad.Aff.Compat, which provides an
AVarAPI methods have changed to match Haskell's
putVarnow blocks until the
AVaractually assimilates the value. Previously,
putVarwould queue the value, but yield immediately. It's possible to recover similar behavior as the old API with
forkAff (try (putVar value avar))(though this should be considered mildly unsafe), or you can use
tryPutVarwhich will attempt a synchronous put.
- Argument order for
Fiberoperations consistently put the subject last.
- Several unlawful instances where removed for
forkAffnow returns a
Fiberrather than a
forkAllwas removed. Just use
cancelwas removed. Use
- The signature of
makeAffhas changed to provide a single callback which takes an
Either Error aargument.
Cancelers are also required. If you are sure you have no means of cancelling an action, you can use
Cancelers no longer yield
Boolean. This was meaningless and not useful, so all cancellation effects now yield
ParAffis no longer a newtype. Parallel computations should be constructed via