Using Azure ServiceBus and the OnMessage call I am looking for a way to determine if the OnMessage event pump stops reading from the queue.
Our connection to OnMessage is configured as below:
protected virtual void DoSubscription(string queueName, Func<QueueRequest, bool> callback)
{
var client = GetClient(queueName, PollingTimeout);
var transformCallback = new Action<BrokeredMessage>((message) =>
{
try
{
var request = message.ToQueueRequest();
if (callback(request))
{
message.Complete();
}
else
{
message.Abandon();
Log.Warn("DoSubscription: Message Failed to Process Gracefully: {0}{1}", Environment.NewLine, JsonConvert.SerializeObject(request));
}
}
catch (Exception ex)
{
Log.Error("DoSubscription: Message Failed to Process With Exception:", ex);
message.Abandon();
}
});
var options = new OnMessageOptions
{
MaxConcurrentCalls = _config.GetInt("MaxThreadsPerQueue"),
AutoComplete = false,
AutoRenewTimeout = new TimeSpan(0,0,1)
};
options.ExceptionReceived += OnMessageError;
client.OnMessage(transformCallback, options);
}
The problem we are encountering is after a period of time with no messages being queued new messages that are queued fail to be picked up by the OnMessage event pump until the application is restarted.
I realize there are ways to do this using Worker Roles, however for monitoring and management purposes we decided to implement this in the Application Start of a web app.
When the delivery count exceeds the limit, the message is moved to the DLQ. The dead-letter reason for the message in DLQ is set to: MaxDeliveryCountExceeded. This behavior can't be disabled, but you can set the max delivery count to a large number.
To peek messages, select Peek Mode in the Service Bus Explorer dropdown. Check the metrics to see if there are Active Messages or Dead-lettered Messages to peek and select either Queue / Subscription or DeadLetter sub-queue. Select the Peek from start button.
The peek-lock mode tells the broker that the receiving client wants to settle received messages explicitly. The message is made available for the receiver to process, while held under an exclusive lock in the service so that other, competing receivers can't see it.
Batch processingBatch processing feature of Azure service bus helps to add and retrieve messages in batch instead of one by one message. This extends help to the systems that have to process bulk messages.
So after a call with Microsoft's Azure support team there is not an event to trap when OnMessage or OnMessageAsync errors. As these are not blocking calls, it starts the event pump and returns to the executing thread, this creates a challenge to determine if OnMessage* is doing it's job.
Suggestions from Microsoft were:
However, I did explore some bullet proofing against OnMessage and discovered a few things which have eased my fears.
All-in-all I'm going to continue using OnMessage/OnMessageAsync for now and keep an eye on it. I will update this if I see issues that change my opinion of OnMessage.
Aside - Make sure if you are using OnMessage for permanent listening in an Azure Web Site that you set the "Always On" configuration option to "On". Otherwise, unless a web request comes in OnMessage will be disposed and messages will no longer be processed until the web application is reawakened by a HTTP request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With