Async/await programming pattern in Haskell - synchronous interface with asynchronous implementation independent of a particular task scheduler
APACHE-2.0 License
Disclaimer: This is not an officially supported Google product.
In this package we explore how to implement the async/await programming pattern such that:
async
to schedule computations in other threads and await
for themThe second condition ensures that even if there is limited amount of threads, thread starvation won't occur. In particular, computations can be run even in a single-threaded environment and are sequenced appropriately.
Note: This is somewhat different approach from the one taken by the async Haskell package, which relies on Haskell threads and blocking waits on compuations using STM.
Note: Currently exceptions are not dealt with.
async
computation should beawait
on it, rather than dying silently.The continuation monad allows a computation to explicitly access the whole code that follows it. Instead of returning its result, it passes it as an argument to a continuation. Among other things, this allows a computation to suspend itself by storing the continuation somewhere, and later and resume it.
When specialized to (a -> IO ()) -> IO ()
, we can work with asynchronous IO
operations in synchronous style. For example, if we schedule computations in
threads, it is possible to write:
do
startThread <- liftIO myThreadId
reschedule
endThread <- liftIO myThreadId
where reschedule
suspends the computation and immediately resumes it in a
different thread. Hence startThread
and endThread
will contain different
values. See also testThreadScheduler
in Async_test.hs
.
The same principle is used when waiting for another computation inside await
.
If the other computation hasn't finished yet, the current continuation is added
to its list of callbacks to invoke once the result is available.