We are in the process of migrating our codebase over from MSMQ to the SQS Transport (latest versions of both). Is there any guidance, documentation or existing scripts for migrating timeouts out of the TimeoutManager NHIbernate persistence table into the SQS delay queues? We have a number of sagas that defer timeouts for many days, in some cases months, and it is not practical to run the MSMQ transport in parallel in order to somehow drain the existing timeouts. Any guidance would be appreciated.
Unfortunately we don’t have guidance for switching timeouts from NHibernate persistence to SQLS delay queues. This sample here shows how to migrate from NHibernate persistence to SQL Transport native timeouts
The scripts there might give you a starting point. I would use those scripts to fetch all the timeouts and then essentially defer all the found timeouts in NHibernate Persistence and then use a dedicated send-only endpoint to defer the appropriate message into the future
var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(TimeSpan.FromMinutes(30));
await endpoint.Send(new MessageToBeSentLater(), sendOptions)
.ConfigureAwait(false);
This repo also contains a branch to move timeouts to a transport but then from RavenDB to RabbitMQ. The process is pretty similar. Read from storage and then defer the messages on the transport.
The good thing about using a send-only endpoint or NServiceBus.Raw (as pointed out by the comment of @ramonsmits) is that you don’t have to deal with the delayed headers really. Because you are going through the AmazonSQS transport dispatcher (transport level infrastructure thing that sends messages) all the appropriate headers and attributes for delaying messages are set automatically. Your responsibility is then only to make sure the payload and the “regular” message headers are set accordingly.
Using the raw Transport makes sense. I was wondering how the send only would’ve dealt with the raw body. I can piece together the rest from here. Thanks @danielmarbach@ramonsmits!
Even if you are not using NSB Raw you can get access to the IDispatchMessages interface for example in a feature startup task. You basically create a feature, add a startup task and declare a dependency to IDispatchMessages in the constructor.