Azure-sdk-for-net: [BUG] - ApproximateMessagesCount is never updated when client is monitoring rather than manipulating queue

Created on 16 Sep 2020  路  10Comments  路  Source: Azure/azure-sdk-for-net

Describe the bug
In the scenario where Producer P is queuing messages into queue Q for consumption by a consumer C, when a monitoring client M periodically checks the queue, the ApproximateMessagesCount is only set the first time that GetPropertieAsync is called and never updated in subsequent calls..

Expected behavior
GetPropertiesAsync should update ApproximateMessageCount

Actual behavior (include Exception or Stack Trace)
ApproximateMessageCount is set on the first call but not on successive calls

To Reproduce

Create a monitoring client...


var queue = ... new QueueClient ...
while (true)
{
  var props = await queue.GetPropertiesAsync().ConfigureAwait(false);
  var count = props.Value?.ApproximateMessagesCount ??0;
  Console.WriteLine($"current count is {count}");
  await Task.Delay(TimeSpan.FromSeconds(5);
}

In this case, the count will be read correctly on the first iteration of the loop but will never subsequently change even though the external producer and consumer are running. (Variations in the message count can also be verified using Azure Storage Explorer)

The workaround is simply to include the QueueClient construction within the loop - it does not appear that there is any other way to force a update of the property set. The old Windows.Azure.Storage library had a RetrieveMessageCount method IIRC.

Environment:

  • Azure.Storage.Blobs 12.4.2

    • VS 16.8.0 pv 3

12:12>dotnet --info
.NET SDK (reflecting any global.json):
Version: 5.0.100-rc.1.20452.10
Commit: 473d1b592e

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19041
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.100-rc.1.20452.10\

Host (useful for support):
Version: 5.0.0-rc.1.20451.14
Commit: 38017c3935

.NET SDKs installed:
3.0.100-preview9-014004 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
3.1.100-preview3-014645 [C:\Program Files\dotnet\sdk]
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.102 [C:\Program Files\dotnet\sdk]
3.1.201 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
5.0.100-rc.1.20452.10 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview7.19365.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview9.19424.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0-preview3.19555.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.0-rc.1.20451.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview7-27912-14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0-preview3.19553.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.0-rc.1.20451.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-preview7-27912-14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.0.0-preview9-19423-09 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.0-preview3.19553.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.0-rc.1.20452.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Client Service Attention Storage customer-reported needs-team-attention question

All 10 comments

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage.

Thank you for your feedback. Tagging and routing to the team best able to assist.

Hi I was wondering what version of Azure.Storage.Queues are you using? (unless that's a typo and you meant the Queues package instead of the Blobs library)

Hi @amnguye - I'm using the latest stable.... "Azure.Storage.Queues" Version="12.4.2" Maybe you were referring to me mentioning "Windows.Azure.Storage" ? I actually meant "WindowsAzure.Storage" (no dot) That was the original (now deprecated) library for accessing all types of Azure resources and had an extra API for explicitly refreshing the message count.

@NeilMacMullen, the clients in v12 are stateless, I'm surprised moving the client constructor within the loop would make a difference.

If messages are constantly being created and consumed, it's going to be challenging to get the "correct" ApproximateMessagesCount, since it's going to be constantly changing. Why type of values are you seeing?

@seankane-msft

If messages are constantly being created and consumed, it's going to be challenging to get the "correct" ApproximateMessagesCount, since it's going to be constantly changing.

Of course - that's why the name is ApproximateMessageCount ! ;-) The point here is not to get the exact number, it is to check that the queue size is not continuously growing because the produce is outrunning the consumer.

Why type of values are you seeing

To expand a bit on this....

In this case, the count will be read correctly on the first iteration of the loop but will never subsequently change even though the external producer and consumer are running

Let's say there are (approximately) 50 messages in the queue. Then the code above will print out some number close to 50 and continue to print out the same number until restarted. When it's restarted, then the number will be "sampled* once again.

I'm surprised moving the client constructor within the loop would make a difference.

The observed behaviour is consistent with an implementation that...

  • reads the instantaneous number of messages in the queue at the point that GetPropertiesAsync is first called
  • short-circuits subsequent calls to GetPropertiesAsync (maybe it incorrectly assumes they are immutable?).

Each call to QueueClient.GetProperties() calls the backend API, it does not short-circuit.

https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Queues/src/QueueClient.cs#L941

You need need to call GetProperties() each time you'd like an updated ApproximateMessageCount, the QueueProperties object will not update on its own.

You need need to call GetProperties() each time you'd like an updated ApproximateMessageCount

Yes, that's exactly what the code I posted in the bug report does. The point is that even after doing this the value of ApproximateMessageCount appears never to change (apart from the very first time the call is made).

Having said that, I'm now unable to reproduce this now so looking more like a bug at my end - apologies.

Great, glad you were able to get it resolved!

Was this page helpful?
0 / 5 - 0 ratings