CCR tips and tricks - part 8

The scatter gather pattern where you spawn multiple tasks and then wait for them all to complete is a common pattern used with CCR. if you have a small, well known number of tasks to spawn the use of a joined receiver combined with a choice for errors can be a slick way of achieving "wait for all to succeed or the first failure". That is assuming that one failure means the whole scatter and gather operation failed.

   1: public IEnumerator<ITask> Fibonacci(
  2:     int n, 
  3:     PortSet<int, Exception> resultPort)
  4: {
  5:     if (n < 0)
  6:     {
  7:         resultPort.Post(new ArgumentOutOfRangeException("n"));
  8:     }
  9:     else if (n <= 1)
 10:     {
 11:         resultPort.Post(n);
 12:     }
 13:     else
 14:     {
 15:         var n1port = Fibonacci(n - 1);
 16:         var n2port = Fibonacci(n - 2);
 17:         var joinedSuccess = Arbiter.JoinedReceive<int, int>(
 18:             false, 
 19:             n1port, 
 20:             n2port, 
 21:             (n1, n2) => resultPort.Post(n1 + n2));
 22:         yield return Arbiter.Choice(
 23:             joinedSuccess,
 24:             Arbiter.Receive<Exception>(false, n1port, resultPort.Post),
 25:             Arbiter.Receive<Exception>(false, n2port, resultPort.Post));
 26:     }
 27: }

This implementations computes a specific Fibonacci number by computing the two parts in parallel. Not the most efficient way to do this but it shows how a joined receiver is used to collect the result but if there is any error it is returned immediately without waiting for the two results. This does not mean that "the other" task is aborted. More on that in a future post in this series.