Interprocess Communication: Part 2

December 3, 2014

Blog | Development | Interprocess Communication: Part 2
Interprocess Communication: Part 2

Welcome to part two in the IPC series! Today, we’ll be taking a look at Message Queues. A queue is something most of us have already experienced in our lives. When you walk into the bank and wait to speak with a bank teller, or hop into your local food mart to pick up a delicious sammich, you line up behind every other soul who arrived before you and wait your turn. The attendant pulls the next person from the line, processes his transaction, and sends him on his way.




Message queues follow the same concept. A message is added to a list, behind all other messages in the list, while the head of the list is extracted and processed by a process acting as the attendant. This is repeated until all tasks in the queue are complete.

With .Net, you can easily leverage the MessageQueue class to create new message queues on a local machine, or to connect to another message queue on a local network.

The message itself is bounded by a 4MB limitation, enforced by the Microsoft Message Queue on Windows platforms; however, cloud offerings for queues such as Azure Queue Storage have an even smaller footprint at only 64KB in size per message. What does that mean for developers? Well, for starters, a message queue should not be looked at as a means to transmit information per se. Instead, it should be used to transmit instructions from the sender to the receiver on how it should act, possibly indicating where the actual relevant information can be found.

For instance, consider a system where a client application will receive a video file and a server application must convert it into a web-accessible format. It may not be feasible to have each individual client application instance responsible for performing the conversion. It also may not be possible to have the client application speak directly to the server application, such as the case where many instances of the client application exist (such as a web app.)

Therefore, the video is simply persisted into a shared memory location (such as a database or network file system) by the client application. That way, the server application can pull the data from the memory location, process it, and place it in its final resting place for the next piece in the system to consume it.

But how would the server application be made aware of an incoming video ready for processing? While we’ve already discussed certain mechanisms for two processes to notify each other, a message queue is a good fit for a situation like this. The reason is that the queue can contain several messages that will simply line up one after the other for processing, in the order they were added – exactly what you would expect in a situation like this.

The client application would persist the video, then place a message in the queue containing the relevant information for the server application (in this case, the location of the input video in the persistence mechanism.)

The server application, using the APIs for accessing a message queue, can simply wait for a message to appear on the queue, dequeue it, extract the video from its location and process it, then move on to the next message until all messages have been processed.

Now, let’s look at some code!


MessageQueue queue;
if (!System.Messaging.MessageQueue.Exists(QueuePath))
{
    Console.WriteLine("Queue does not exist yet. Creating...");
    queue = System.Messaging.MessageQueue.Create(QueuePath);
}
else
{
    Console.WriteLine("Queue already exists. Connecting...");
    queue = new System.Messaging.MessageQueue(QueuePath, QueueAccessMode.Send);
}

using (queue)
{
    queue.Formatter = MessageFormatter;

    var doLoop = true;
    do
    {
        Console.Write("Message to send ("exit" to quit): ");
        var line = Console.ReadLine();
        queue.Send(line);
        doLoop = (line != "exit");
    } while (doLoop);
}

The above code will first check if the queue exists at the path specified, and either create or access it with QueueAccessMode.Send permissions. Then, a message captured from the user is sent into the queue, formatted using the Formatter specified. As I mentioned earlier, the actual message added to the queue has size limitations; however, that doesn’t necessarily mean that only String based objects can be stored. The .Net framework provides the BinaryMessageFormatter and XmlMessageFormatter to convert any object into a representation that can be serialized and deserialized by the Queue.

The full source for the above example can be found here.

Stay tuned! Next time in the IPC Series, we’ll be looking at Pipes!

 

Phil Azzi, Developer, GeekHive

Phil Azzi

Technical Lead
Tags
  • Patterns & Practices
  • Tutorial

Recent Work

Check out what else we've been working on