Particular / NServiceBus.Transport.Msmq

MSMQ transport for NServiceBus
https://docs.particular.net/nservicebus/msmq/
Other
5 stars 11 forks source link

Delayed delivery: split setup from initialize #712

Closed mikeminutillo closed 3 weeks ago

mikeminutillo commented 4 weeks ago

Fixes:

In v2 of the transport, the IDelayedMessageStore.Initialize(...) method is only called if the transport is creating queues. This method includes parameters (queue name, transaction mode) which the store needs to do its job.

This PR adds a new interface IDelayedMessageStoreWithInfrastructure. This interface implements IDelayedMessageStore but adds a new method SetupInfrastructure(CancellationToken).

/// <summary>
/// An <see cref="IDelayedMessageStore" /> that sets up infrastructure.
/// </summary>
public interface IDelayedMessageStoreWithInfrastructure : IDelayedMessageStore
{
    /// <summary>
    /// Create tables or other infrastructure. e.g. creates required database artifacts etc.
    /// Called after <see cref="IDelayedMessageStore.Initialize(string, TransportTransactionMode, CancellationToken)"/>.
    /// </summary>
    /// <param name="cancellationToken">The cancellation token set if the endpoint begins to shut down while the SetupInfrastructure method is executing.</param>
    Task SetupInfrastructure(CancellationToken cancellationToken = default);
}

If a delayed delivery store implements this interface, then Initialize(...) is always called when the transport starts (even if the transport is not creating queues). SetupInfrastructure(...) is only called if the transport is creating queues.

If the delayed delivery store only implements IDelayedMessageStore, then the behavior is unchanged to preserve backwards compatibility.

The SqlServerDelayedMessageStore which is shipped as part of this package has been updated to use the new interface.

Custom store

If you have developed a custom delayed message store and the transport is configured to create queues (the default), then no change is required. Your custom delayed message store will work as is.

If you have developed a custom delayed message store and have configured the transport to not create queues, then make the following changes:

  1. Change your custom delayed message store class to implement IDelayedMessageStoreWithInfrastructure instead of IDelayedMessageStore.
  2. Add an implementation of the ISetupInfrastructure(...) method.
  3. Move any infrastructure setup code from Initialize(...) to SetupInfrastructure(...). If there are any variables created in Initialize(...) that are needed in SetupInfrastructure(...) store them as fields in the class as Initialize(...) is called first.