-
Notifications
You must be signed in to change notification settings - Fork 37
Description
Describe the bug
Description
When sending a delayed message with a very low delay e.g. 1ms, the message is sometimes processed ~30s later.
This is on an endpoint that is not doing anything else.
Expected behavior
The delayed message should be processed fairly soon after 1ms.
Actual behavior
Messages are sometimes processed ~30s later
Versions
9.2.7
Steps to reproduce
- Start NSB
- wait ~30s
- Send a delayed message with a delay 1ms
- See that it does not get processed until 30s or so later on.
Relevant log output
Additional Information
Suspected Cause
This looks like a race condition between when the sql transaction is committed and when the in memory BackOffStrategy decides to look for a message.
For example when sending a delayed message with a delay of 1ms:
It looks as though when DelayedMessageTable.Store() is called, it first writes the message to the DB:
var messageRow = StoreDelayedMessageCommand.From(message.Headers, message.Body, dueAfter, destination);
using (var command = connection.CreateCommand())
{
command.Transaction = transaction;
command.CommandText = storeCommand;
command.CommandType = CommandType.Text;
messageRow.PrepareSendCommand(command);
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
}before the transaction is committed it calls:
OnStoreDelayedMessage?.Invoke(null, DateTime.UtcNow.Add(dueAfter));which in turns calls RegisterNewDueTime(DateTime dueTime), which can result in checking for Delayed Messages within the next 1ms.
It could look for this message before the transaction commits.
Which results in no messages being found resulting in the delay before looking again increasing.
This then results in a large delay before processing the message.