Proposal: Control.Concurrent.Async

Simon Marlow marlowsd at
Tue Jun 12 12:33:56 CEST 2012

On 09/06/2012 09:50, Chris Kuklewicz wrote:
> Your superset API is excellent.  I have one important suggestions: non-blocking
> killThread.
> By default, when your combinators like 'withAsync' and 'concurrently' use
> 'cancel' or 'killThread' they should use it in a non-blocking way.  The exported
> 'cancel'&  'cancelWith' should be unchanged and their documention should note
> that they are blocking.
> Consider 'concurrently'.  Perhaps there need to to be two 'concurrently'
> versions?  One is blocking-killThread and guarantees that both are done or dead
> when it returns and the other is non-blocking-killThread and returns ASAP.
> Neither can be turned into the other by the user.
> Rather than API duplication the 'concurrently' operation could get a new
> parameter that selects blocking vs non-blocking killThread.
> Hmmm.... the root problem is some Async tasks that, probably due to foreign
> calls, are uninterpretable.  Maybe the user could label which Async tasks must
> be killed blocking or non-blocking.  The default is non-blocking to avoid
> infecting other threads with uninterpretable calls.  When the user needs the
> extra property of guaranteed kills the user can change the label.  I have no
> immediate idea whether a mutable or immutable label would be better.

I appreciate that sometimes cancel may block and that you may want a 
non-blocking cancel, but I don't think that should be the default.

Firstly, the user might find it surprising if when withAsync has 
returned, the Async still performs some more operations (that are not 
inside an exception handler).  I think it's an important guarantee that 
this doesn't happen - otherwise, what can you say with any certainty 
about the behaviour of withAsync?

Secondly, asynchronous cancel is easily implemented by the user, as

   asyncCancel = async . cancel

what a lovely definition :-)  We even get to decide later on to wait for 
the cancel to happen, by waiting on the result of asyncCancel, and we 
can cancel the asyncCancel itself.

Thirdly, asynchronous cancel is less efficient than synchronous cancel, 
because it involves forking a new thread.

I will document carefully that we are using the synchronous cancel and 
the implications of that, and I'll add asyncCancel.


More information about the Libraries mailing list