Message Pump in Azure Service Bus

Message Pump in Azure Service Bus
Azure Service Bus comes equipped with ways to handle immediate handling messages where we need it. Photo - Mroux Bulikowska / Unsplash

Despite the assumptions that an Azure Service Bus Queue must be polled and then dequeued manually for messages in client code, there is a tiny and neat way to automatically dequeue messages as soon as they arrive. It is an alternative to setting up a Service Bus Triggered Azure Function which would have the same effect. We call this automatic method to respond like this a Message Pump, as it is an event driven way to pick our message without writing additional polling logic.

Here is a quick example of this:


private class MessagePump
{
    private static QueueClient queueClient { get; set; }

    private static void Main(string[] args)
    {
        //make sure the service bus connection string has no EntityPath
        queueClient = new QueueClient("{ServiceBusConnectionString}", "{ServiceBusQueueName}");

        var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
        {
            MaxConcurrentCalls = 1,
            AutoComplete = true, //set to true, if false you must Complete each message after processing 
        };
        //register the message pump here to do something with messages
        queueClient.RegisterMessageHandler(DoSomething, messageHandlerOptions);
        Console.WriteLine($"Now Ready to receive messages");
        Console.Read();

    }

    private static Task DoSomething(Message message, CancellationToken token)
    {
        string messageBody = Encoding.UTF8.GetString(message.Body);

        Console.WriteLine($"Received message: {messageBody}");
        return Task.CompletedTask;
    }

    private static Task ExceptionReceivedHandler(Microsoft.Azure.ServiceBus.ExceptionReceivedEventArgs args)
    {
        //Handle errors here
        return Task.CompletedTask;
    }

}

Quick code for automatically dequeuing message from Service Bus queue without polling logic

And as we push messages from message producers, they get automatically dequeued in our client code. However it's important to remember that if you choose to set the messageHandlerOptions AutoComplete flag to False, you will need to Complete each message with:

await queueClient.CompleteAsync(message.SystemProperties.LockToken);

Completing the message, either through the AutoComplete flag or through manually Completing it from the queue client will make sure it is not received again by your client if it is sent again. Here, I use the Service Bus Explorer in Azure (from the Service Bus instance's menu) to easily send messages through to the Service Bus Queue:

Sending message to Service Bus Queue messages from Explorer in Azure

To conclude, it should be remembered that queue systems in the cloud are generally geared to assist us in load levelling. Often times, we want to lighten the load on our processing systems by delaying when messages can be process and allow them to sit in the queue for their Time To Live period rather than processing them as soon as we receive them in the queue.

Once finished, remember to DELETE any unused resources in Azure.