I am having a Saga and complete message handler as below. Saga initiates multiple messages and then expects reply back.
public class CustomSaga : Saga<CustomSagaData>, IAmStartedByMessages<StartSagaMessage>, IHandleMessages<CompletedMessage>
{
public async Task Handle(StartSagaMessage message, IMessageHandlerContext context)
{
// Send multiple messages to be handled by some other handler
// All the messages are of the same type and is handled by a single handler
for(int messageNo = 0; messageNo < 10; messageNo +)
{
// Send messages
// Set the Saga Data to pending for these messages
Data.Status[messageNo] = Status.IN_PROGRESS
}
}
public async Task Handle(CompletedMessage message, IMessageHandlerContext context)
{
// Handle reply messages by the handler.
// Update Saga Data with the correct status, which is got from the CompletedMessage
Data.Status[message.messageNo] = message.Status;
// Check if any pending message is present, if not complete
// PROBLEM
if(!Data.Status.Any(status => status.Value == MessageStatus.IN_PROGRESS))
{
// Execute some custom finishing logic.
MarkAsComplete();
}
}
}
public class CustomSagaData: ContainSagaData
{
public virtual string OperationId { get; set; }
public virtual IDictionary<int, MessageStatus> Status{ get; set; }
}
public enum MessageStatus {
IN_PROGRESS, COMPLETED, FAILED
}
public CompletedMessage {
public int MessageId {get; set;}
public MessageStatus Status {get; set;}
}
I am referring to the line where I am checking for the Saga status(Please refer the line where I have put the comment “PROBLEM”)
The Data would be the same for multiple messages which are processed in parallel and will lead to the custom finishing logic not to be executed.
Can you please let us know what would be the best practice for marking a saga complete which handles multiple messages.