STM should become the unifying framework in Haskell for waiting on any combo:
- internal application events
- I/O completion notification
- time-based notification
Async is one good way to use these things.
In future we are likely to have async I/O operations that are lower overhead than just starting a thread and doing a synchronous I/O operation.
As a taster of what this may look like, consider the existing (low level) API in Control.Concurrent
threadWaitReadSTM :: Fd -> IO (STM.STM (), IO ())
threadWaitWriteSTM :: Fd -> IO (STM.STM (), IO ())
Currently these are not widely used, partly because they are only supported on the threaded RTS, and they are not used in higher level abstractions.
These should be able to be wrapped in an Async, but currently cannot because they do not have a ThreadId. That's because they really do not have a ThreadId! They are much lower overhead than using a whole thread. But they do have an STM completion-wait action, and a way to kill/cancel the async action, and they could be equipped with a suitable unique identifier.
It would be nice to be able to lift this into the async representation and then compose it with other async things.
In future we will likely have better support for threadDelay like this, using STM and cancellation. And also a much wider range of I/O: real file & socket reads and writes and a myriad of others.
What we would need is a generalisation of the Async representation:
data Async a = Async
{ asyncThreadId :: {-# UNPACK #-} !ThreadId
-- ^ Returns the 'ThreadId' of the thread running
-- the given 'Async'.
, _asyncWait :: STM (Either SomeException a)
}
The _asyncWait is fine. The asyncThreadId would need to be generalised to something that can be:
- compared, for Eq, Ord, Hashable
- used for cancellation
STM should become the unifying framework in Haskell for waiting on any combo:
Async is one good way to use these things.
In future we are likely to have async I/O operations that are lower overhead than just starting a thread and doing a synchronous I/O operation.
As a taster of what this may look like, consider the existing (low level) API in
Control.ConcurrentCurrently these are not widely used, partly because they are only supported on the threaded RTS, and they are not used in higher level abstractions.
These should be able to be wrapped in an
Async, but currently cannot because they do not have aThreadId. That's because they really do not have aThreadId! They are much lower overhead than using a whole thread. But they do have an STM completion-wait action, and a way to kill/cancel the async action, and they could be equipped with a suitable unique identifier.It would be nice to be able to lift this into the async representation and then compose it with other async things.
In future we will likely have better support for
threadDelaylike this, using STM and cancellation. And also a much wider range of I/O: real file & socket reads and writes and a myriad of others.What we would need is a generalisation of the
Asyncrepresentation:The
_asyncWaitis fine. TheasyncThreadIdwould need to be generalised to something that can be: