Skip to content

Commit 19b48ed

Browse files
feat: Enhance queue creation with instance-specific settings. Now supports AutoDeleteOnIdle.
1 parent 04a46ff commit 19b48ed

File tree

4 files changed

+53
-6
lines changed

4 files changed

+53
-6
lines changed

src/Transport/Administration/QueueCreator.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class QueueCreator(AzureServiceBusTransport transportSettings)
1111
{
1212
static readonly ILog Logger = LogManager.GetLogger<QueueCreator>();
1313

14-
public async Task Create(ServiceBusAdministrationClient adminClient, string[] queues,
14+
public async Task Create(ServiceBusAdministrationClient adminClient, string[] queues, string? instanceName = null,
1515
CancellationToken cancellationToken = default)
1616
{
1717
foreach (var address in queues)
@@ -25,6 +25,15 @@ public async Task Create(ServiceBusAdministrationClient adminClient, string[] qu
2525
EnablePartitioning = transportSettings.EnablePartitioning
2626
};
2727

28+
// Only apply AutoDeleteOnIdle if an instance name is provided to avoid unintentional deletions
29+
// of shared queues, e.g. error.
30+
if (instanceName is not null
31+
&& string.Equals(instanceName, address, StringComparison.Ordinal)
32+
&& transportSettings.AutoDeleteOnIdle is not null)
33+
{
34+
queue.AutoDeleteOnIdle = transportSettings.AutoDeleteOnIdle.Value;
35+
}
36+
2837
try
2938
{
3039
await adminClient.CreateQueueAsync(queue, cancellationToken).ConfigureAwait(false);

src/Transport/Administration/TopologyCreator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ namespace NServiceBus.Transport.AzureServiceBus;
66

77
class TopologyCreator(AzureServiceBusTransport transportSettings)
88
{
9-
public async Task Create(ServiceBusAdministrationClient adminClient, string[] queues,
9+
public async Task Create(ServiceBusAdministrationClient adminClient, string[] queues, string? instanceName = null,
1010
CancellationToken cancellationToken = default)
1111
{
1212
var topologyCreator = new MigrationTopologyCreator(transportSettings);
1313
await topologyCreator.Create(adminClient, cancellationToken).ConfigureAwait(false);
1414

1515
var queueCreator = new QueueCreator(transportSettings);
16-
await queueCreator.Create(adminClient, queues, cancellationToken).ConfigureAwait(false);
16+
await queueCreator.Create(adminClient, queues, instanceName, cancellationToken).ConfigureAwait(false);
1717
}
1818
}

src/Transport/AzureServiceBusTransport.cs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,15 @@ await administrationClient.AssertNamespaceManageRightsAvailable(cancellationToke
118118
.ToArray();
119119

120120
var queueCreator = new TopologyCreator(this);
121-
await queueCreator.Create(administrationClient, allQueues, cancellationToken).ConfigureAwait(false);
121+
122+
// Pass in the instance specific queue address (if it exists) so that the queue creator can set the
123+
// AutoDeleteOnIdle (if set) only on that queue and not on shared queues like error.
124+
string? instanceReceiverAddress = null;
125+
if (infrastructure.Receivers.TryGetValue("InstanceSpecific", out var instanceReceiver))
126+
{
127+
instanceReceiverAddress = instanceReceiver.ReceiveAddress;
128+
}
129+
await queueCreator.Create(administrationClient, allQueues, instanceReceiverAddress, cancellationToken).ConfigureAwait(false);
122130

123131
foreach (IMessageReceiver messageReceiver in infrastructure.Receivers.Values)
124132
{
@@ -133,7 +141,6 @@ await subscriptionManager.SetupInfrastructureIfNecessary(cancellationToken)
133141
}
134142

135143
return infrastructure;
136-
137144
}
138145

139146
void ApplyRetryPolicyOptionsIfNeeded(ServiceBusClientOptions options)
@@ -201,6 +208,36 @@ public int EntityMaximumSize
201208

202209
internal int EntityMaximumSizeInMegabytes => EntityMaximumSize * 1024;
203210

211+
/// <summary>
212+
/// Gets or sets the maximum time period that a queue can remain idle before Azure Service Bus automatically deletes it.
213+
/// </summary>
214+
/// <value>The idle timeout after which unused entities are automatically deleted. The minimum allowed value is 5 minutes.</value>
215+
/// <remarks>
216+
/// <para>
217+
/// This property controls the AutoDeleteOnIdle setting for queues created by the transport.
218+
/// When an entity has no messages and no active connections for the specified duration,
219+
/// Azure Service Bus will automatically delete it to help manage resource cleanup.
220+
/// See <see href="https://learn.microsoft.com/en-us/azure/service-bus-messaging/advanced-features-overview#autodelete-on-idle"/>.
221+
/// </para>
222+
/// <para>
223+
/// Setting this value can be useful for temporary queues (dynamically scaling endpoints that make use of 'MakeInstanceUniquelyAddressable') that should be cleaned up automatically
224+
/// when they are no longer being used. However, be cautious when setting this for production endpoints as it may result in unexpected entity deletion during periods of low activity.
225+
/// </para>
226+
/// </remarks>
227+
/// <exception cref="ArgumentOutOfRangeException">Thrown when the value is less than 5 minutes.</exception>
228+
public TimeSpan? AutoDeleteOnIdle
229+
{
230+
get;
231+
set
232+
{
233+
if (value.HasValue)
234+
{
235+
ArgumentOutOfRangeException.ThrowIfLessThan(value.Value, TimeSpan.FromMinutes(5), nameof(AutoDeleteOnIdle));
236+
}
237+
field = value;
238+
}
239+
}
240+
204241
/// <summary>
205242
/// Enables entity partitioning when creating queues and topics.
206243
/// </summary>

src/Transport/AzureServiceBusTransportInfrastructure.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ void WriteStartupDiagnostics(StartupDiagnosticEntries startupDiagnostic) =>
6464
UseWebSockets = transportSettings.UseWebSockets.ToString(),
6565
TimeToWaitBeforeTriggeringCircuitBreaker = transportSettings.TimeToWaitBeforeTriggeringCircuitBreaker.ToString(),
6666
CustomTokenProvider = transportSettings.TokenCredential?.ToString() ?? "default",
67-
CustomRetryPolicy = transportSettings.RetryPolicyOptions?.ToString() ?? "default"
67+
CustomRetryPolicy = transportSettings.RetryPolicyOptions?.ToString() ?? "default",
68+
AutoDeleteOnIdle = transportSettings.AutoDeleteOnIdle?.ToString() ?? "default",
6869
});
6970

7071
IMessageReceiver CreateMessagePump(ReceiveSettings receiveSettings, ServiceBusClient receiveClient)

0 commit comments

Comments
 (0)