views:

353

answers:

1

Having a complex sequence of tasks, implementing error handling can quickly bloat the code when using try/catch blocks and stuff like Choice receivers on PortSet<ActualResult, Exception> for every little task.

Thankfully the CCR seems to offer a mechanism to handle exceptions in a more general way for a graph of tasks: causalities. A typical example looks like this:

Port<Exception> exceptionPort = new Port<Exception>();
Dispatcher.AddCausality(new Causality("some job", exceptionPort));
Arbiter.Activate(
  dispatcherQueue,
  Arbiter.Receive(false, exceptionPort, ex => Console.WriteLine(ex)));
// now schedule the real tasks

In my case, I have a computing intensive application using the CCR to implement a scatter/gather scenario, splitting "jobs" into a bunch of parallelized tasks. (Besides that, more then one of these jobs can run at the same time.) In case that one task fails, I want to to stop all the remaining tasks in the job, but not any other job. (The results are of no use to me if I'm missing a piece of the puzzle, so continuing to work on this would be just a waste of CPU time.)

The question is what the best way would be to implement the stopping.

One idea would be:

  1. Create one single Dispatcher instance and keep it over application lifetime.
  2. Create a new DispatcherQueue for every "job" (a group of tasks). Add the Causality immediately after creating the DispatcherQueue.
  3. In the handler for the exception queue, call Suspend() on the DispatcherQueue.
  4. Before disposing the dispatcher queue, remove the causality.

I wonder if this suggestion can be regarded best practice, or if there is a better approach to deal with such a - probably fairly common - scenario.

+1  A: 

Seems like a good way to way to go about it to me.

Crayon Violent