Azure / azure-sdk-for-net

This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
MIT License
5.47k stars 4.8k forks source link

[FEATURE REQ] Add Support To Remove Deferred State From Messages #45908

Closed Babbel404 closed 1 month ago

Babbel404 commented 1 month ago

Library name

Azure.Messaging.ServiceBus

Please describe the feature.

Request

Currently the operation to defer a message is a one way operation. As a Service Bus Entity Manager I would like the ability to programmatically restore a message state to Active from Deferred.

Use Case

Scenario

As a Service Bus Entity manager I need the ability to manage queues and topic/subscriptions with fine-grain control over what messages I operate on. In my event driven system there are a large number of events coming from an external source. Sometimes there are values contained within these messages that cause issues. Under this scenario these messages are dead-lettered. It can be assumed that there exists some property about the messages that I can use to identify which messages were dead-lettered for a given reason. Sometimes this could be the DeadLetterReason other times this could be the EnqueuedTimeUtc, the actual property used to determine which messages I want to requeue or delete is not important.

Solution / Current Problem

I have successfully created a management application that can subscribe to Dead Letter sub queues and perform management actions on my behalf. This application can operate on any number of messages in the queue and perform actions based on filter criteria provided.

Actions:

However, I cannot fully implement the Preserve functionality. Ideally, messages would retain their current position on the Dead Letter queue. To my knowledge, this cannot be done without introducing an external system to store the messages. This has forced me to either Requeue or Delete these messages in order to find messages that match my search criteria on the queue.

I have created a version of this application that can use message deferral to set messages aside in the dead letter queue that do not match the search criteria. However, after this operation is done, I cannot restore the state to Active for these messages. This is problematic as it leaves me with limited options for these messages:

Because the Dead Letter queue is a sub queue I cannot requeue the dead letter messages directly to the sub queue. So this is also not an option. Even if this were an option, it would be less desirable, as it would modify the message sequence order.

Example

Here is a contrived example that can help illustrate how this feature would help. I ask that the use case be evaluated at a more general level than just Dead Letter messages, as being able to utilize deferred messages in a normal queue may also make sense for some workflows.

Queue: MetrologyResultProcessZProcessor Info: Apply the logic for process Z to all messages from the MetrologyResult stream Volume: 10,000 - 100, 000 messages per hour

A change occurred in the measurement process that produces the metrology result for specific parts. This change caused several similar but unrelated failures in the code for a few part types. Part types C-145, R-872 and E-21 are known at this time to be impacted, however there could be other failures. There are currently 500,000 messages in the dead letter queue from this event, and potentially other unrelated failures.

The development team has published a fix for the MetrologyResultProcessZProcessor code that should address the issues in C-145 and R-872 and they have requested a small subset of the data be reprocessed from the dead letter queue, 100 messages each. After processing and validating the results for these initial messages, all dead letter messages for C-145 and R-872 should be requeued.

I would like to iterate over the dead letter messages and cherry pick out matching messages to reprocess. I want to perform this action in a durable way, and I would prefer if messages that did not match were left un-altered

Additional Notes

I feel that a simple code modification in the MessageReceiver similar to here we could expose a method to RestoreActive or RemoveDeferral. This new method simply needs to expose a way to interact with the AMQP Receiver DisposeMessageRequestResponseAsync and change the ManagementConstants.Properties.DispositionStatus

I can submit a PR with the codes changes I think are required if that would be helpful. However, I wanted to confirm that this is behavior that can be supported. I am unsure if there are technical restrictions surrounding the deferred messages, specifically around having ~500,000 deferred messages in a queue. Would this impact the normal receive performance of the queue?

Sorry for the long request, and thank you for your time and consideration.

github-actions[bot] commented 1 month ago

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

jsquire commented 1 month ago

Hi @Babbel404. Thanks for reaching out and for your suggestions. To the best of our knowledge, the requested operations are not supported by the Service Bus contract and would require service changes. I've transferred this over to the Service Bus repository as #716 and engaged the Service Bus product manager for confirmation.

If I'm mistaken, I've asked him to reactivate this request and provide the relevant contract details so that we can consider your request. For now, I'm going to close this out.