Concurrency in .NET - Learning from Erlang

I'm finally getting back to my concurrency in .NET posts after a brief hiatus after I got sidetracked on various other functional programming issues such as some language oriented programming and functional C#.  In the previous post, I talked about MPI in .NET and I need to get back to that one and address some of the issues raised in the next post in this series.  But, in the mean time, let's focus on another area of concurrency through message passing.  This time, let's bring Erlang into the picture.

Learning Erlang

For some of the upcoming talks about F# and functional programming I have planned, I will be putting a lot of the focus on concurrency programming through asynchronous and parallel mechanisms.  F# is not only a well established functional programming language, but its libraries also lend well to concurrency oriented programming.

But, with these adventures, I've always wanted to reach outside my comfort zone and learn from a language that had concurrency in mind from the start.  That made me turn my attention to Erlang.  Some of my motivations came from not only learning a new language, which is always nice, but also to learn some of the concurrency and messaging patterns so that I can apply that to F#. 

In my learnings, I've compiled a list of resources that can help you learn Erlang.  This includes books, podcasts and screencasts that you might find helpful for a good deep dive into the language.

Podcasts
Books
Screencasts
The Northern Virginia Ruby Users Group (NOVARUG) have recently started the NoVA Languages Group which has the goal of learning new languages to add to their toolbelt.  The group picked Erlang as the first language to learn and is currently going through the Programming Erlang book.  If you're in the DC area and interested in learning Erlang, I'd highly recommend that you join the group.

Erlang Style Message Passing in F#

To bring this back to F# for just a moment, we can apply some of the lessons learned from Erlang to F#.  Today we'll look at a simple kind of message processing called mailbox processing.  This pattern is popular in the Erlang language and has been applied to F#.  The mailbox is a message queue that you can scan for relevant messages to your message processing agents.  The MailboxProcessor class controls this action and is defined in the Microsoft.FSharp.Control.Mailboxes namespace.

This will be a simple example of how to send and receive messages using a single mailbox processor.  We can define a message type that will encompass our data.  This usually comprises of a receive, a send, and a stop.  But, the great thing is that it's not limited to that.  We'll use async workflows (yet another post I need to do) to process the message itself, hence why you see the return! statements in there.

#light

open Microsoft.FSharp.Control.CommonExtensions
open Microsoft.FSharp.Control.Mailboxes

type Message = Phrase of string | Fetch of IChannel<string> | Stop

type MessageAgent() =
  let agent = MailboxProcessor.Start(fun inbox ->
    let rec loop (phrase : string) =
      async {
              let! msg = inbox.Receive()
              match msg with
              | Phrase item ->
                return! loop(item)
              | Stop ->
                return ()
              | Fetch replyChannel ->
                do replyChannel.Post(phrase)
                return! loop(phrase)
            }
    loop(string.Empty)
  )
 
   member x.Send(s) = agent.Post(Phrase(s))
   member x.Stop() = agent.Post(Stop)
   member x.Fetch() = agent.PostAndReply(fun replyChannel -> Fetch(replyChannel))

What I'm also doing is defining handling logic for each message type, the stop, the fetch and the receiving of a phrase.  If it's a stop message, we return immediately, else if it's a phrase, we'll go ahead and loop on the given item, and once we're ready to fetch it, then we'll go ahead and post it.  After that, I'll go ahead and expose three methods which will allow external access to sending and receiving messages, as well as stopping.

Now, that I have done the basic plumbing for handling messaging like this, then we can go ahead and start sending messages to it and receiving.

let agent = new MessageAgent()

agent.Send("Hello world!")
let result1 = agent.Fetch()
printfn "Message result1: %s" result1

agent.Send("Hello world again!")
let result2 = agent.Fetch()
printfn "Message result2: %s" result2

This is a pretty naive example and just to show the basics of how it could be used.  I'm not going to pretend it's anywhere near as powerful as the Erlang message passing libraries, but it's a pretty good start.

Robert Pickering has a pretty good example of Erlang style message passing here.  F# also comes with a sample using the MailboxProcessor for a program called ConcurrentLife which is located in the Samples directory of your F# installation.

Retlang

But, what about those in the C# world?  Is there a solution?  An interesting piece that came up during the look into concurrency in .NET led me back to Retlang, which is a takeoff on Erlang by the author Mike Rettig.  I had looked at this previously when Ayende did a brief look back in November here.  The framework itself borrows a few ideas from Scala in terms of the event-based actors.  Let's take a look at a quick example of sending and receiving messages on it.

static void Main(string[] args)
{

    IProcessContextFactory factory = new ProcessContextFactory();
    factory.Start();
    IProcessContext publisher = factory.CreateAndStart();
    IProcessContext consumer = factory.Create();

    consumer.Subscribe<int>(new TopicEquals("retlang"), (header, id) => Console.WriteLine(id));
    consumer.Start();

    for (int i = 0; i < 25; i++)
        publisher.Publish("retlang", i);
   
    publisher.Stop();
    publisher.Join();

    consumer.Stop();
    consumer.Join();
   
    factory.Stop();
}

Looks to be a well designed architecture and I'll continue to look at this a bit further.  In the mean time, check out Mike's blog for more information.

Wrapping It Up

I hope this brief introduction will get you excited about looking at other functional programming languages and what they can do for you.  If not to learn them and apply them in your daily work, but to understand the concepts behind them is rather powerful and should be part of your learning plan anyhow.  These above examples of implementations in other languages should help you along.

But, what do I think of Erlang overall?  It's too early to tell.  Even though the language has been around for a while, it has seen a recent resurgance.  With the Pragmatic Programmers throwing their weight behind the language, who's to say?  But I think it'd take a bit to push this as yet another language with a virtual machine into the mix over say the JVM, CLR, and so on.  Instead, maybe we'll see an implementation on top of .NET, or just applying the lessons learned from it such as we've seen in F#.  It was funny to listen to Joe Armstrong think pretty much the same thing as maybe the language won't take off, but the ideas can and ultimately will.

kick it on DotNetKicks.com

No Comments