public async Task SubscribeToDeadLetterAsync(Func <PunchyMessage, Task> onMessageAsync, string groupId, CancellationToken cancellationToken, params string[] topics) { topics = topics.Select(topic => TopicNameHelpers.BuildDeadLetterTopicName(topic, groupId)).ToArray(); await SubscribeAsync(onMessageAsync, groupId, cancellationToken, topics); }
public async Task OnMessageAsync(IMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } var badMessageNextLevel = TopicNameHelpers.ExtractBadMessageNextLevel(message.Topic); string badMessageNextLevelTopicName; if (badMessageNextLevel == badMessageMaxLevels) { badMessageNextLevelTopicName = TopicNameHelpers.BuildDeadLetterTopicName(message.Topic, groupId); } else { badMessageNextLevelTopicName = TopicNameHelpers.BuildBadMessageTopicName(message.Topic, badMessageNextLevel, groupId); } var attempts = new List <Attempt>(); var badMessageCandidate = message; message = GetSourceMessage(badMessageCandidate, attempts); // If message is null, retry time not ellapsed so will ignore this message for now. // It will be read again latter if (message != null) { try { await onMessageAsync.Invoke(new PunchyMessage() { MessageAddress = message.MessageAddress, MessageBytes = message.MessageBytes, Timestamp = message.Timestamp, Topic = message.Topic, Attempts = attempts }); } catch (Exception exception) { if (badMessageNextLevel < badMessageMaxLevels) { logger.LogWarning(exception, "Action failed for message, moving to bad message level '{BadMessageNextLevel}'. " + "Will try again in {RetrySeconds}. Topic: {Topic}; Original message address: {@MessageAddress}", badMessageNextLevel, configuration.LevelDelaysInSeconds[badMessageNextLevel], message.Topic, message.MessageAddress); } else // is final level { logger.LogError(exception, "Action failed for message, will NOT try again. Topic: {Topic}; Original message address: {@MessageAddress}", message.Topic, message.MessageAddress); } var badMessageContents = new BadMessageContents() { Exception = exception, SourceMessageAddress = badMessageCandidate.MessageAddress }; await pubSub.PublishAsync(badMessageNextLevelTopicName, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(badMessageContents))); } await badMessageCandidate.CommitAsync(); } }