CCR tips and tricks - part 18

The CCR interleave is a very powerful construct to create read/write type of locking but on steroids. It allows you to create a concurrent group and an exclusive group of handlers. Concurrent handlers will execute concurrently as long as no exclusive handler is pending. Exclusive handlers will execute exclusively. It is however important to remember that the exclusive handler is not re-entrant and if an exclusive handler posts to a port with a handler in the same exclusive group, the second handler will not execute until the first one completes so the first handler cannot wait for a result from the second one.

Another related problem is when you want a persistent handler but you only want it to execute one handler at a time. Remember that if there is a handler waiting on a port, as soon as a message is posted a handler task is added to the task queue so if you have a persistent handler and post ten times to that port fast; ten tasks will be scheduled and hence they will run concurrently. Instead of using an interleave you can fake an exclusive persistent handler with something similar to tail recursion.

   1: public void WithTailRecursion()
  2: {
  3:     var responsePort = new Port<int>();
  4:     Arbiter.Activate(
  5:         dispatcherQueue, 
  6:         Arbiter.Receive(false, excusivePort, RecursiveHandler));
  7:     excusivePort.Post(1);
  8:     excusivePort.Post(2);
  9:     excusivePort.Post(3);
 10:     excusivePort.Post(4);
 11: }
 12:  
 13: private void RecursiveHandler(int n)
 14: {
 15:     try
 16:     {
 17:         DoSomeWork(n);
 18:     }
 19:     finally
 20:     {
 21:         Arbiter.Activate(
 22:             dispatcherQueue, 
 23:             Arbiter.Receive(false, excusivePort, RecursiveHandler));
 24:     }
 25: }

The important thing is to make sure the receiver is always added again, even for unexpected exceptions. Since messages in ports are stored in a FIFO queue and only one handler is executing at any time messages will be handled in order as they arrive on the port.