private async Task SaveMessageData(MessageData messageData) { if (messageData != null) { _log.Info($"Saving the message data for message with ID {messageData.MessageId} into the message store."); } await _msgStorage.InsertOrUpdate(messageData); }
/// <summary> /// Checks the loaded saga data to see if the message currently being handled is a duplicate of a message that has previously been handled. /// If that is the case, message dispatch is skipped, but any messages stored as outgoing messages from previously handling the incoming message will be sent. /// </summary> public async Task Process(IncomingStepContext context, Func <Task> next) { var message = context.Load <Message>(); var messageId = message.GetMessageId(); var transactionContext = context.Load <ITransactionContext>(); object temp; if (transactionContext.Items.TryGetValue(Keys.MessageData, out temp)) { _log.Info($"Checking if message with ID {messageId} has already been processed before."); var messageData = (MessageData)temp; if (messageData.HasAlreadyHandled(messageId)) { _log.Info($"Message with ID {messageId} has already been handled"); var outgoingMessages = messageData .GetOutgoingMessages() .ToList(); if (outgoingMessages.Any()) { _log.Info("Found {0} outgoing messages to be (re-)sent... will do that now", outgoingMessages.Count); foreach (var messageToResend in outgoingMessages) { foreach (var destinationAddress in messageToResend.DestinationAddresses) { await _transport.Send(destinationAddress, messageToResend.TransportMessage, transactionContext); } } } else { _log.Info("Found no outgoing messages to be (re-)sent..."); } } else { _log.Info($"Message with ID {messageId} has not been handled yet."); if (await _msgStorage.IsProcessing(messageId)) // does the message have an assigned thread id? { _log.Info($"Message with ID {messageId} is ignored as it already is being processed."); // ignore the message or maybe return as in 'Assigned' state // todo: should we retry once a message has been assigned for too long? What is too long? By default 5m? return; } var threadId = Thread.CurrentThread.ManagedThreadId; _log.Info($"Updating message storage for the message with ID {messageId} as being processed by thread {threadId}"); // insert the message or update it with the current input queue address, the current thread id and the current date messageData.InputQueueAddress = _transport.Address; messageData.ProcessingThreadId = threadId; messageData.TimeThreadIdAssigned = DateTime.UtcNow; await _msgStorage.InsertOrUpdate(messageData); // hand the message of to the next pipeline step await next(); _log.Info($"Marking the message with ID {messageId} as been handled."); messageData.MarkMessageAsHandled(); } } else { // The LoadMessageDataStep was not triggered await next(); } }