private async Task OnArticlePublishedAsync(Messages.ArticlePublished msg) { try { IUnitOfWorkInternal uow = (IUnitOfWorkInternal)await reactorRepo.LoadAsync(msg.SubscribingReactorId); // guard race condition where a reactor has already caught up bool alreadyReacted = uow.PersistedPubSub // have we already delivered this publication (and if so, have we already seen this version or later)? .Map(previous => previous.PublicationDeliveries.Any(sub => sub.PublicationId == msg.PublicationId && sub.VersionNumber >= msg.VersionNumber)) .GetOrElse(false); if (alreadyReacted) { logger.LogInformation($"ReactorId {msg.SubscribingReactorId} in bucket {msg.ReactorBucket} received article {msg.Name} on subscription id {msg.SubscriptionId} from publishing reactor id {msg.PublishingReactorId} to but the article version {msg.VersionNumber} had already been delivered"); logger.LogDebug("{@PublicationDeliveries}", uow.PersistedPubSub.Get().PublicationDeliveries); return; } //react to msg await uow.Reactor.ReactAsync(msg, uow); uow.RecordDelivery(msg); //persist await uow.CompleteAndPublishAsync(); } catch (Exception ex) { logger.LogError(ex, $"ReactorID {msg.SubscribingReactorId} threw exception after receiving ArticlePublished message (Subscription TopicName={msg.Name},PublishingReactorId={msg.PublicationId},SubscribingReactorId={msg.SubscribingReactorId},Subscription={msg.SubscriptionId}"); } }
public ArticlePublished ToMessage() { if (string.IsNullOrWhiteSpace(Name)) { throw new ArgumentNullException("Name property was not set correctly during persistance"); } var type = Type.GetType(ArticleSerialisationType, throwOnError: true); var msg = new Messages.ArticlePublished( SubscribingReactorBucket, Name, SubscribingReactorId, PublishingReactorId, VersionNumber, SubscriptionId, PublicationId, JsonConvert.DeserializeObject(ArticleSerialisation, type) ); return(msg); }