Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Odd Behavior of Azure Service Bus ReceiveBatch()

Working with a Azure Service Bus Topic currently and running into an issue receiving my messages using ReceiveBatch method. The issue is that the expected results are not actually the results that I am getting. Here is the basic code setup, use cases are below:

    SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName);

    IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100);
        foreach (BrokeredMessage message in messageList)
        {
            try
            {
                Console.WriteLine(message.GetBody<string>() + message.MessageId);

                message.Complete();
            }
            catch (Exception ex)
            {
                message.Abandon();
            }
        }

    client.Close();
    MessageBox.Show("Done");
  1. Using the above code, if I send 4 messages, then poll on the first run through I get the first message. On the second run through I get the other 3. I'm expecting to get all 4 at the same time. It seems to always return a singular value on the first poll then the rest on subsequent polls. (same result with 3 and 5 where I get n-1 of n messages sent on the second try and 1 message on the first try).

  2. If I have 0 messages to receive, the operation takes between ~30-60 seconds to get the messageList (that has a 0 count). I need this to return instantly.

  3. If I change the code to IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0)); then issue #2 goes away because issue 1 still persists where I have to call the code twice to get all the messages.

I'm assuming that issue #2 is because of a default timeout value which I overwrite in #3 (though I find it confusing that if a message is there it immediately responds without waiting the default time). I am not sure why I never receive the full amount of messages in a single ReceiveBatch however.

like image 803
B-Stewart Avatar asked Aug 11 '15 18:08

B-Stewart


Video Answer


2 Answers

The way I got ReceiveBatch() to work properly was to do two things.

  1. Disable Partitioning in the Topic (I had to make a new topic for this because you can't toggle that after creation)
  2. Enable Batching on each subscription created like so:
  3. List item

SubscriptionDescription sd = new SubscriptionDescription(topicName, orgSubName); sd.EnableBatchedOperations = true;

After I did those two things, I was able to get the topics to work as intended using IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new TimeSpan(0,0,0));

like image 176
B-Stewart Avatar answered Nov 11 '22 14:11

B-Stewart


I'm having a similar problem with an ASB Queue. I discovered that I could mitigate it somewhat by increasing the PrefetchCount on the client prior to receiving the batch:

SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName);

client.PrefetchCount = 100;

IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100);

From the Azure Service Bus Best Practices for Performance Improvements Using Service Bus Brokered Messaging:

Prefetching enables the queue or subscription client to load additional messages from the service when it performs a receive operation.

...

When using the default lock expiration of 60 seconds, a good value for SubscriptionClient.PrefetchCount is 20 times the maximum processing rates of all receivers of the factory. For example, a factory creates 3 receivers, and each receiver can process up to 10 messages per second. The prefetch count should not exceed 20*3*10 = 600.

...

Prefetching messages increases the overall throughput for a queue or subscription because it reduces the overall number of message operations, or round trips. Fetching the first message, however, will take longer (due to the increased message size). Receiving prefetched messages will be faster because these messages have already been downloaded by the client.

like image 42
John Hoerr Avatar answered Nov 11 '22 16:11

John Hoerr