Added handler for removing orphaned subscriptions

This commit is contained in:
Raymond den Haan 2024-02-13 14:35:39 +01:00
parent 14993d466f
commit 4d5f191fbc
5 changed files with 52 additions and 10 deletions

View file

@ -47,7 +47,25 @@ services
if (useMassTransit)
{
elsa.UseMassTransit();
elsa.UseMassTransit(massTransit =>
massTransit.UseAzureServiceBus(azureServiceBusConnectionString, serviceBusFeature => serviceBusFeature.ConfigureServiceBus = bus =>
{
bus.PrefetchCount = 4;
bus.LockDuration = TimeSpan.FromMinutes(5);
bus.MaxConcurrentCalls = 32;
bus.MaxDeliveryCount = 8;
// etc.
})
// massTransit.UseRabbitMq(rabbitMqConnectionString, rabbit => rabbit.ConfigureServiceBus = bus =>
// {
// bus.PrefetchCount = 4;
// bus.Durable = true;
// bus.AutoDelete = false;
// bus.ConcurrentMessageLimit = 32;
// // etc.
// }))
);
}
});

View file

@ -22,6 +22,7 @@ public static class ModuleExtensions
void Configure(AzureServiceBusFeature bus)
{
bus.AzureServiceBusOptions = options => options.ConnectionStringOrName = connectionString;
bus.ConnectionString = connectionString;
configure?.Invoke(bus);
}

View file

@ -36,6 +36,11 @@ public class AzureServiceBusFeature : FeatureBase
/// </summary>
public Action<IServiceBusBusFactoryConfigurator>? ConfigureServiceBus { get; set; }
/// <summary>
/// A delegate to configure <see cref="AzureServiceBusOptions"/>.
/// </summary>
public Action<AzureServiceBusOptions> AzureServiceBusOptions { get; set; } = _ => { };
/// <summary>
/// A delegate to create a <see cref="ServiceBusAdministrationClient"/> instance.
/// </summary>
@ -98,7 +103,9 @@ public class AzureServiceBusFeature : FeatureBase
}
var genericType = consumerInterface.GetGenericArguments()[0];
var topicName = $"{genericType.Namespace.ToLower()}~{genericType.Name.ToLower()}";
//While the name might show up in the Azure portal with a ~, the separator is actually an /
//see https://learn.microsoft.com/en-us/archive/blogs/servicebus/azure-service-bus-azure-resource-manager-and-this-character
var topicName = $"{genericType.Namespace.ToLower()}/{genericType.Name.ToLower()}";
subscriptionTopology.Add(new MessageSubscriptionTopology(topicName,
consumer.Name ?? genericType.Name.ToLower(),
@ -112,6 +119,7 @@ public class AzureServiceBusFeature : FeatureBase
/// <inheritdoc />
public override void Apply()
{
Services.Configure(AzureServiceBusOptions);
Services.AddScoped(ServiceBusAdministrationClientFactory);
Services.AddNotificationHandler<OrphanedSubscriptionRemover>();
}

View file

@ -8,7 +8,9 @@ namespace Elsa.MassTransit.AzureServiceBus.Handlers;
/// <summary>
/// Class responsible for removing orphaned subscriptions.
/// </summary>
public class OrphanedSubscriptionRemover(MessageTopologyProvider topologyProvider, ServiceBusAdministrationClient client)
public class OrphanedSubscriptionRemover(
MessageTopologyProvider topologyProvider,
ServiceBusAdministrationClient client)
: INotificationHandler<InstanceDeactivated>
{
/// <summary>
@ -16,13 +18,26 @@ public class OrphanedSubscriptionRemover(MessageTopologyProvider topologyProvide
/// </summary>
public async Task HandleAsync(InstanceDeactivated notification, CancellationToken cancellationToken)
{
var subscriptions = topologyProvider.GetShortLivedSubscriptions().ToList();
foreach (var subscription in subscriptions)
var subscriptionTopology = topologyProvider.GetShortLivedSubscriptions().ToList();
foreach (var subscription in subscriptionTopology)
{
await client.DeleteSubscriptionAsync(subscription.TopicName,
$"Elsa-{notification.InstanceName}-{subscription.SubscriptionName}",
cancellationToken);
// Get subscriptions based on topics instead of the topology since when names are longer than 50 characters
// MassTransit automatically truncates them.
await foreach (var asbSubscription in client.GetSubscriptionsAsync(subscription.TopicName,
cancellationToken))
{
if (asbSubscription.SubscriptionName.StartsWith($"Elsa-{notification.InstanceName}-"))
{
var queueName = asbSubscription.ForwardTo.Substring(asbSubscription.ForwardTo.LastIndexOf('/') + 1);
await Task.WhenAll(
client.DeleteSubscriptionAsync(subscription.TopicName,
asbSubscription.SubscriptionName,
cancellationToken),
client.DeleteQueueAsync(queueName, cancellationToken));
}
}
}
}
}

View file

@ -8,5 +8,5 @@ public class AzureServiceBusOptions
/// <summary>
/// Th connection string or connection string name to connect with the service bus.
/// </summary>
public string ConnectionStringOrName { get; set; } = default!;
public string? ConnectionStringOrName { get; set; }
}