Azure ServiceBus OnMessage is blocking the call or not?

We use Azure ServiceBus queues to handle large volumes of client requests. However, the call OnMessage

appears to be a blocking call, however, blocking that call is incredibly inconsistent if it is indeed a blocking call.

What I'm trying to accomplish is to keep track of the queue permanently from the web service application (to resolve the metric from the running application)

I am creating a subscription below:

protected virtual void Subscribe(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();
            }
        }
        catch (Exception ex)
        {
            //TODO: Log the error
            message.Abandon();
        }
    });
    var options = new OnMessageOptions
    {
        MaxConcurrentCalls = _config.GetInt("MaxThreadsPerQueue"),
        AutoComplete = false
    };
    options.ExceptionReceived += OnMessageError;
    client.OnMessage(transformCallback, options);
}

      

If I only have a one-time subscription, the application stops watching the queue and thus stops processing messages. However, if I put a while loop in my call to subscribe. So with much hesitation, I wrote the below snippet to re-submit if this one is OnMessage

complete.

protected void MonitorQueue()
{
    IsRunning = true;
    while (IsRunning)
    {
        try
        {
            Log.Info("MonitoringThread: OnMessage beginning logging for {0}", QueueName);
            QueueClient.Subscribe(QueueName, Processor);
            Log.Info("MonitoringThread:  OnMessage ended logging for {0}", QueueName);
        }
        catch (Exception ex)
        {
            IsRunning = false;
            Log.Error("MonitoringThread: Error in subscription for {0}: ", ex, QueueName);
        }

        if (SleepBeforeReinit > 0 && IsRunning)
        {
            Thread.Sleep(SleepBeforeReinit);
        }
    }
}

      

This fixed the issue of messages ending with a dead letter due to not being raised, however it caused other problems.

When OnMessage is a billable operation, it bothers me when I see a log file telling me that the queue starts and ends in less than a second and my log file grows in size very quickly.

I have it set to MessagingFactory

OperationTimeout

OperationTimeout

1 day, but that doesn't seem to affect the frequency of the subscription open / close status as I expected.

I have seen many examples of doing this as a worker role, however this will not do what we are trying to do. I am currently plugging this in from the Global.asax.cs of our web app. Any advice is appreciated!

+3


source to share


2 answers


OnMessage and OnMessageAsync DO NOT block calls. They need to be instantiated in one go and will continue to subscribe to the queue until the application is finished.



For details, see the related post: Azure Service Bus, Determine If OnMessage Stops Processing

+1


source


Your first approach is correct, and the MaxThreadsPerQueue value determines how many threads are available to process your messages. It seems that these threads have been used up (maybe it takes a while to process your messages with the callback?).



Instead, you can use the QueueClient.OnMessageAsync Method to receive your messages.

0


source







All Articles