Retlang - Concurrency Library for C#
I have been investigating Retlang as a way to handle concurrency in Rhino ETL. There are quite a few samples there, but no over all explanation, I am going to document what I find as I learn them.
Retlang is based on the concept of message passing in C#, a typical pub/sub infrastructure, within a single a process. As such, you always need to know where you are publishing to, and where to reply. The message header serves as a way to decouple the two. So you can build loosely coupled components that talks to each other by message passing.
Obviously, my first step when evaluating a library is checking how well it plays with my own semantics, and I have to say that on first glance, Retlang looks really nice.
I am starting to explore it, and I am impressed. There is, for me, a sense of very well designed API. In fact, I have encountered several instances of thinking "I would have done it like this", only to encounter exactly that thing within the code.
The minimal example is this one:
IProcessContextFactory factory = new ProcessContextFactory(); factory.Start(); IProcessContext publisher = factory.CreateAndStart(); IProcessContext consumer = factory.Create(); consumer.Subscribe<int>(new TopicEquals("test"), delegate (IMessageHeader header, int id) { Console.WriteLine(id); }); consumer.Start(); for (int i = 0; i < 50; i++) { publisher.Publish("test", i); }consumer.Stop();
publisher.Stop();
consumer.Join();
publisher.Join();factory.Stop();
This just publish a list of numbers and print them, but it demonstrate several imprtant factors in Retlang. First of which, we have the publish / subscribe mechanism, but we also have the topic select which we pass to the subscribe method. This implementation is a very good one for extensibility, and it mimics Erlang's pattern matching capabilities to a high degree.
Threading concerns:
I am not an expert yet, but as far as I can tell, each IProcessContext is running in its own thread, and the IProcessContextFactory has another thread as well, the bus thread. All the contextes screated from a single factory share the same bus space. This means that you probably do not want to have too many Process Contextes around, but you can register as many subscribiers as you want, and they will be routed appropriately.
Again, those are just my observations on how it works, from an initial survery only, so it is entirely possible (and probable) that I am entirely mistaken.
Comments
The current design does use a thread per process context and a thread for the underlying message bus. I've experimented with using a thread pool and lightweight contexts, but haven't committed to an implementation yet.
Here is a blog entry with some of my ramblings on the subject.
http://www.jroller.com/mrettig/entry/lightweight_threads_in_net
Mike
0.2.2.0 has been released which includes lightweight process contexts. Contexts can be created with dedicated threads or use a shared thread pool.
http://code.google.com/p/retlang/
Comment preview