Angel \”Java\” Lopez on Blog

October 12, 2010

AjAgents: a new implementation

Filed under: .NET, AjAgents, Open Source Projects — ajlopez @ 9:51 am

Some time ago, I wrote about my project AjAgents, describing it, implementing genetic algorithms and other mini demos. The project is base in the send of messages to “agents” (I could named them actors, or something else, never mind). The agents received the messages and process them one by one. Each instance of an agent don’t need to manage concurrency: the messages are queued in an internal queue by each agent (I could reimplement this feature using a queue for many agents, if needed).

But my previous implementations relied on reflection, or CCR library by Microsoft (see my previous posts). Now, I take another way: an agent is a wrapper around a normal object. The source code can be download from my AjCodeKatas Google Code project, under trunk/AjAgents folder.

The key interface is:

    public interface IAgent<T>
    {
        void Post(Action<T> action);
    }

The new idea: to use a generic class. T is the type of our “classical” type (no agent), and Post is the method to invoke an action over the inner object: an action that is a “routine” receiving a T instance as parameter. So, if the inner object has a method

inner.DoSomething(parameter);

it can be invoked as a message from the agent as:

agent.Post(x => x.DoSomething(1));

There is a base agent implementation:

    public class Agent<T> : IAgent<T>
    {
        private T instance;
        private AgentQueue<T> queue;
        private bool running;
        public Agent(T instance)
        {
            this.instance = instance;
        }
        public void Post(Action<T> action)
        {
            if (!this.running)
                this.Start();
            this.queue.Enqueue(action);
        }
        private void Start()
        {
            lock (this)
            {
                if (this.running)
                    return;
                this.queue = new AgentQueue<T>();
                Thread thread = new Thread(new ThreadStart(this.Execute));
                thread.IsBackground = true;
                thread.Start();
                this.running = true;
            }
        }
//...
    }

Note that Post method enqueues the action in an internal queue. The process of that queue is in the method .Execute (not shown). The queue is a blocking one (I know, there is one in .NET 4.0, but my code runs under 3.x, and under 2.x versions, I guess):

    public class AgentQueue<T>
    {
        private Queue<Action<T>> queue = new Queue<Action<T>>();
        private int maxsize;
        public AgentQueue()
            : this(100)
        {
        }
        public AgentQueue(int maxsize)
        {
            if (maxsize <= 0)
                throw new InvalidOperationException("AgentQueue needs a positive maxsize");
            this.maxsize = maxsize;
        }
        public void Enqueue(Action<T> action)
        {
            lock (this)
            {
                while (this.queue.Count >= this.maxsize)
                    Monitor.Wait(this);
                this.queue.Enqueue(action);
                Monitor.PulseAll(this);
            }
        }
        public Action<T> Dequeue()
        {
            lock (this)
            {
                while (this.queue.Count == 0)
                    Monitor.Wait(this);
                Action<T> action = this.queue.Dequeue();
                Monitor.PulseAll(this);
                return action;
            }
        }
    }

I applied TDD for the development of all these classes, one example test:

        [TestMethod]
        public void InvokeIncrement()
        {
            ManualResetEvent handle = new ManualResetEvent(false);
            Counter counter = new Counter();
            Agent<Counter> agent = new Agent<Counter>(counter);
            agent.Post(c => { c.Increment(); handle.Set(); });
            handle.WaitOne();
            Assert.AreEqual(1, counter.Count);
        }

Most of the above code was derived (err… copy and paste :-) from my own work on AjSharp (channels, queues, agents… ).

I have a proof of concept demo using this new AjAgents implementation (my “classical” web crawler). But that is a topic for a future post.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Theme: Shocking Blue Green. Get a free blog at WordPress.com

Follow

Get every new post delivered to your Inbox.

Join 67 other followers