skip to Main Content

I am working with an azure service bus queue configured to be FIFO (First input first output). I work on an order application with the following states "Pending", "Received" and "Sent". therefore I have grouped the messages by the "SessionId" service bus option, setting the orderId as sessionId so that it processes the messages in order in case of horizontal scaling.

So far it works perfectly, the problem I have found is when a message in "pending" or "Received" status fails due to a timeout and goes to the dead letter queue. The message in "sent" status is processed correctly and then when the support team re-sends the "Pending" or "Received" status message to the queue it is processed correctly marking the order in a previous status instead of "sent" ".

I can think of several ways to control this, for example that the support team looks at the status of the order before reprocessing the message from the dead letter queue 🙂 but I would like to know if service bus offers the possibility that if there is a message in the dead letter queu all the messages in the session queue that have the same sessionId go to the dead letter queu. Finallly, my question is:

Is there a way to configure azure service bus so that if there are any messages in the dead letter queue it sends all messages with the same sessionId to the dead letter queue?

Thank you very much!!!

2

Answers



  1. You can try this code to read Dead Letter from Queue.

    public static async Task GetMessage()
            {
                string topic = "myqueue1";
                string connectionString = "Endpoint = sb://xxx.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxx";
                
                var servicebusclient = new ServiceBusClient(connectionString);
                var reciveroptions = new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter };
                var reciver = servicebusclient.CreateReceiver(topic, reciveroptions);
                // 10 number of message read from Queue
                await receiver.PeekMessageAsync(10);
                
            }
    

    after receiving message from Dead Letter you can send to queue.

    As per Microsoft official documents

    There’s no automatic cleanup of the DLQ. Messages remain in the DLQ
    until you explicitly retrieve them from the DLQ and call Complete() on
    the dead-letter message.

    These following document help you.

    Thanks Casually Coding for posting post on Read Message from the Dead Letter Queue

    Microsoft Documents Using Dead-Letter Queues to Handle Message Transfer Failures , Receive Message from Dead letter queue

    Login or Signup to reply.
  2. I would like to know if service bus offers the possibility that if there is a message in the dead letter queue all the messages in the session queue that have the same sessionId go to the dead letter queue.

    No, there is no such offering by Service Bus by default.

    Is there a way to configure azure service bus so that if there are any messages in the dead letter queue it sends all messages with the same sessionId to the dead letter queue?

    Yes, you can do that. You can first peek the messages in your dead-letter queue to fetch all the session ids. Then you can receive the messages in your main queue whose session id is in the DLQ, and then move those messages to DLQ. Here’s one such logic I’ve implemented in dot net using the latest version of Service Bus SDK.

    var queueName = "<queue>";
    var connectionString = "<connection-string>";
    
    var client = new ServiceBusClient(connectionString);
    
    var sessionIdInDLQList = new List<string>();
    var receiver = client.CreateReceiver(queueName, new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter });
    var message = await receiver.PeekMessageAsync();
    while (message != null)
    {
        if (!sessionIdInDLQList.Contains(message.SessionId))
            sessionIdInDLQList.Add(message.SessionId);
        message = await receiver.PeekMessageAsync();
    }
    
    foreach (var sessionId in sessionIdInDLQList)
    {
        var session = await client.AcceptSessionAsync(queueName, sessionId);
        message = await session.ReceiveMessageAsync(TimeSpan.FromSeconds(20));
        while (message != null)
        {
            await session.DeadLetterMessageAsync(message, "Message with this session is to be dead-lettered!");
            message = await session.ReceiveMessageAsync(TimeSpan.FromSeconds(20));
        }
    }
    

    In your case, you need to do this before your consumers start reading the messages, probably you can write this in your consumer application or any trigger application like Azure Function or worker role. That’s upto your method of handling.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search