-
Notifications
You must be signed in to change notification settings - Fork 98
Description
This is one for discussion rather than a bug... Consider the following code:
catchExit (receiveWait [ match (\(m :: SomeType) -> doSomething m) ])
(\pid (e :: ProcessExitException) -> handleExFrom e pid) When receiveWait goes into a blocking read on the mailbox, exceptions are masked, however this is not the case when receiveWait is running a handler for which a match has succeeded. It is thus very easy to handle an exit signal, having mutated our mailbox and subsequently lost a message.
Now, this isn't necessarily wrong - though it would be nice to have ways of dealing with it more elegantly - and I think what I've realised here is why the safe-exceptions package won't let you catch async exceptions. They're meant to terminate your thread.
When we introduced catchExit and friends, the intention was to mimic Erlang's exit trapping behaviour. Specifically, how this works is that if you evaluate process_flag(trap_exit, true), then all future exit signals do not terminate the process, but instead arrive in the mailbox in the form {'EXIT', From, Reason}. I do not think we can (or should) try to emulate that behaviour in Cloud Haskell, and I understand now why @edsko was reluctant when we first asked for it. I do think we need to have a clear method of signalling requested vs. unexpected termination to processes, for proper supervision methods to work. But I feel the base primitives are easily misunderstood and will lead to complex bugs if not used carefully.
@qnikst and I were discussing some other exception handling options that we could add as optional APIs in addition to receiveWait, and these might be useful. At a minimum, I think we need to document this situation though, so that users aren't caught out by surprise.