Isard
Isard

Reputation: 312

MassTransit Courier resends activity after a while

I implemented routing slip with a bunch of activities. One of them performs long-running process in Azure that takes even 15-20min. I noticed that after 10 minutes, while the process is still running, the activity gets executed again. It breaks the whole routing slip, because the first process is still in progress and a retry produces an error.

I am using Azure Service Bus as a message broker. I couldn't find any reference to this topic in the documentation so I'm wondering whether this is specific to the Courier and it can be changed so that it does not redeliver at all or is this some kind of an incorecct behaviour?

EDIT:

Here's the code after the changes:

services.AddMassTransit(c =>
{
    c.SetEndpointNameFormatter(new DefaultEndpointNameFormatter(false));

    c.AddConsumersFromNamespaceContaining<TestConsumer>();

    c.AddActivitiesFromNamespaceContaining<ActivityBase<IArguments, LogBase>>();
    
    c.UsingAzureServiceBus((ctx, cfg) =>
    {
        cfg.Host(hostContext.Configuration.GetConnectionString("connection_string"));
        
        cfg.LockDuration = TimeSpan.FromMinutes(25);
        cfg.MaxAutoRenewDuration = TimeSpan.FromMinutes(25);
        cfg.MaxDeliveryCount = 1;
        
        cfg.ConfigureEndpoints(ctx);
    });
});

Upvotes: 0

Views: 505

Answers (1)

Chris Patterson
Chris Patterson

Reputation: 33268

The message is likely being redelivered by Azure Service Bus, due to the length of time required to consume the message.

On the receive endpoint, the MaxAutoRenewDuration is used to adjust the maximum time to renew the message lock, which is passed directly to the Azure client library. The default value is five minutes, which is the same as the default LockDuration. You can increase this time to the maximum expected time for the activity to complete.

Optionally, you can change the MaxDeliveryCount property to 1, so that Azure will only attempt to the deliver the message once, after which if the lock times out and is not renewed, it will move the message to the dead-letter queue for that receive endpoint.

UPDATE: If you're configuring this in an Activity Definition, you can do so as shown:

public class CustomActivityDefinition :
    ActivityDefinition<TActivity, TArguments, TLog>
{
    protected override void ConfigureExecuteActivity(IReceiveEndpointConfigurator endpointConfigurator, IExecuteActivityConfigurator<TActivity, TArguments> executeActivityConfigurator)
    {
        if(endpointConfigurator is IServiceBusReceiveEndpointConfigurator sb)
        {
            sb.MaxDeliveryCount = 1;
            sb.MaxAutoRenewDuration = TimeSpan.FromMinutes(67);
        }
    }
}

Upvotes: 1

Related Questions