Search code examples
c#.netazureservicebusmasstransitservicebus

.NET - Service bus - Moving a message to DLQ


I am using Azure Service Bus with Mass Transit library in a .NET WebApi application. I have a ServiceA where I publish my StartProccess message. This message is also used in the state machine - StartStateMachine.

This message goes to ServiceB (it is Azure Functions) where it is processed and sent on. I am forced to register the consumer for ServiceB in ServiceA using the following notation, because from what I have found and read, the subscription must pre-exist for Azure Functions. Normally, I would do this registration using MassTransit, but MassTransit cannot create a consumer without a "bind" - a consumer implementation. This is because the consumer is in a different project/service.

if (!(await adminClient.TopicExistsAsync(formatter.MessageName<StartProccess>()));
    adminClient.CreateTopicAsync(formatter.MessageName<StartProccess>());
    
if (!(await adminClient.SubscriptionExistsAsync(formatter.MessageName<StartProccess>()), formatterCheckFunc.ConsumerFromMessageName<StartProccess>()).Value)
    await adminClient.CreateSubscriptionAsync(new CreateSubscriptionOptions(formatter.MessageName<StartProccess>(), formatterCheckFunc.ConsumerFromMessageName<StartProccess>()) { MaxDeliveryCount = 1 });

The reason the max delivery count is listed here is so that when the consumer crashes on exception, it doesn't run ten times again. I want to achieve functionality like mass transit, which in case of an error immediately calls the IFault implementation and does not repeat the call.

Everything works as it should. However, once in a while and really rarely for example 1 in 100 times I get a StartProccess message that ends up in the DLQ with a message - maximum number of sends was exceeded. I don't understand why. It really sets it once in a long while. This way my state machine doesn't start and it's really clumsy.

enter image description here

Has anyone encountered this problem? Thank you

Edit:

Message handling

    try
    {
        await _receiver.HandleConsumer<Consumer>(TopicName, SubscriptionName, message, cancellationToken);
        await messageActions.CompleteMessageAsync(message);
    }
    catch (SomeException ex)
    {
        await messageActions.AbandonMessageAsync(message);
        _log.LogWarning("LogIt");
    }
    catch
    {
        // This?
        await messageActions.CompleteMessageAsync(message);
        // Or this?
        await messageActions.DeadLetterMessageAsync(message);
        throw;
    }

Solution

  • Everything works as it should. However, once in a while and really rarely for example 1 in 100 times I get a StartProccess message that ends up in the DLQ with a message - maximum number of sends was exceeded.

    Setting MaxDeliveryCount to 1 is what’s causing it.

    Value of one means a single processing attempt. If that single attempt is unsuccessful for any reason, the message will be dead lettered.