private async Task SendOutboxMessagesAsync() { var jobId = Guid.NewGuid().ToString("N"); _logger.LogDebug($"Started processing outbox messages... [job id: '{jobId}']"); var stopwatch = new Stopwatch(); stopwatch.Start(); var messages = await _outbox.GetUnsentAsync(); _logger.LogDebug($"Found {messages.Count} unsent messages in outbox [job id: '{jobId}']."); if (!messages.Any()) { _logger.LogDebug($"No messages to be processed in outbox [job id: '{jobId}']."); return; } var publishTasks = messages.Select(om => _publisher.PublishAsync(om.Message, om.MessageId, om.CorrelationId, om.SpanContext, om.MessageContext, om.Headers)); await Task.WhenAll(publishTasks); await _outbox.ProcessAsync(messages); stopwatch.Stop(); _logger.LogDebug($"Processed {messages} outbox messages in {stopwatch.ElapsedMilliseconds} ms [job id: '{jobId}']."); }
private async Task SendOutboxMessagesAsync(object state) { var messages = await _outbox.GetUnsentAsync(); var publishTasks = messages.Select(om => _publisher.PublishAsync(om.Message, om.MessageId, om.CorrelationId, om.SpanContext, om.MessageContext, om.Headers)); await Task.WhenAll(publishTasks); await _outbox.ProcessAsync(messages); }
public async Task StartAsync(CancellationToken cancellationToken) { while (true) { var messages = await _outbox.GetUnsentAsync(); var publishTasks = messages.Select(om => _publisher.PublishAsync(om.Message, om.MessageId.ToString())); await Task.WhenAll(publishTasks); await _outbox.ProcessAsync(messages); await Task.Delay(2000, cancellationToken); } }
public async Task SendAsync <T>(T message, string originatedMessageId = null, string messageId = null, string correlationId = null, string spanContext = null, object messageContext = null, IDictionary <string, object> headers = null) where T : class { if (!Enabled) { _logger.LogWarning("Outbox is disabled, outgoing messages won't be saved into the storage."); return; } var outboxMessagesSet = _dbContext.Set <OutboxMessage>(); var outboxMessage = new OutboxMessage { Id = string.IsNullOrWhiteSpace(messageId) ? Guid.NewGuid().ToString("N") : messageId, OriginatedMessageId = originatedMessageId, CorrelationId = correlationId, SpanContext = spanContext, SerializedMessageContext = messageContext is null ? EmptyJsonObject : JsonConvert.SerializeObject(messageContext, SerializerSettings), MessageContextType = messageContext?.GetType().AssemblyQualifiedName, Headers = (Dictionary <string, object>)headers, SerializedMessage = message is null ? EmptyJsonObject : JsonConvert.SerializeObject(message, SerializerSettings), MessageType = message?.GetType().AssemblyQualifiedName, SentAt = DateTime.UtcNow }; await outboxMessagesSet.AddAsync(outboxMessage); await _dbContext.SaveChangesAsync(); } async Task <IReadOnlyList <OutboxMessage> > IMessageOutboxAccessor.GetUnsentAsync() { var outboxMessagesSet = _dbContext.Set <OutboxMessage>(); var outboxMessages = await outboxMessagesSet.Where(om => om.ProcessedAt == null).ToListAsync(); return(outboxMessages.Select(om => { if (om.MessageContextType is {}) { var messageContextType = Type.GetType(om.MessageContextType); om.MessageContext = JsonConvert.DeserializeObject(om.SerializedMessageContext, messageContextType, SerializerSettings); } if (om.MessageType is {})
public async Task SendAsync <T>(T message, string messageId = null, string correlationId = null, string spanContext = null, object messageContext = null, IDictionary <string, object> headers = null) where T : class { if (!Enabled) { _logger.LogWarning("Outbox is disabled, messages will not be sent."); return; } var outboxMessage = new OutboxMessage { Id = Guid.NewGuid(), MessageId = messageId, CorrelationId = correlationId, SpanContext = spanContext, SerializedMessageContext = messageContext is null ? EmptyJsonObject : JsonConvert.SerializeObject(messageContext, SerializerSettings), MessageContextType = messageContext?.GetType().AssemblyQualifiedName, Headers = (Dictionary <string, object>)headers, SerializedMessage = message is null ? EmptyJsonObject : JsonConvert.SerializeObject(message, SerializerSettings), MessageType = message?.GetType().AssemblyQualifiedName, SentAt = DateTime.UtcNow }; await _repository.AddAsync(outboxMessage); } async Task <IReadOnlyCollection <OutboxMessage> > IMessageOutboxAccessor.GetUnsentAsync() { var outboxMessages = await _repository.FindAsync(om => om.ProcessedAt == null); return(outboxMessages.Select(om => { if (om.MessageContextType is {}) { var messageContextType = Type.GetType(om.MessageContextType); om.MessageContext = JsonConvert.DeserializeObject(om.SerializedMessageContext, messageContextType, SerializerSettings); } if (om.MessageType is {})
public async Task SendAsync <T>(T message, string originatedMessageId = null, string messageId = null, string correlationId = null, string spanContext = null, object messageContext = null, IDictionary <string, object> headers = null) where T : class { if (!Enabled) { _logger.LogWarning("Outbox is disabled, outgoing messages won't be saved into the storage."); return; } var outboxMessage = new OutboxMessage { Id = string.IsNullOrWhiteSpace(messageId) ? Guid.NewGuid().ToString("N") : messageId, OriginatedMessageId = originatedMessageId, CorrelationId = correlationId, SpanContext = spanContext, SerializedMessageContext = messageContext is null ? EmptyJsonObject : JsonSerializer.Serialize(messageContext, SerializerOptions), MessageContextType = messageContext?.GetType().AssemblyQualifiedName, Headers = (Dictionary <string, object>)headers, SerializedMessage = message is null ? EmptyJsonObject : JsonSerializer.Serialize(message, SerializerOptions), MessageType = message?.GetType().AssemblyQualifiedName, SentAt = DateTime.UtcNow }; await _outboxRepository.AddAsync(outboxMessage); } async Task <IReadOnlyList <OutboxMessage> > IMessageOutboxAccessor.GetUnsentAsync() { var outboxMessages = await _outboxRepository.FindAsync(om => om.ProcessedAt == null); return(outboxMessages.Select(om => { if (om.MessageContextType is not null) { var messageContextType = Type.GetType(om.MessageContextType); om.MessageContext = JsonSerializer.Deserialize(om.SerializedMessageContext, messageContextType, SerializerOptions); } if (om.MessageType is not null) { var messageType = Type.GetType(om.MessageType); om.Message = JsonSerializer.Deserialize(om.SerializedMessage, messageType, SerializerOptions); } return om; }).ToList()); } Task IMessageOutboxAccessor.ProcessAsync(OutboxMessage message) => _outboxRepository.Collection.UpdateOneAsync( Builders <OutboxMessage> .Filter.Eq(m => m.Id, message.Id), Builders <OutboxMessage> .Update.Set(m => m.ProcessedAt, DateTime.UtcNow)); Task IMessageOutboxAccessor.ProcessAsync(IEnumerable <OutboxMessage> outboxMessages) => _outboxRepository.Collection.UpdateManyAsync( Builders <OutboxMessage> .Filter.In(m => m.Id, outboxMessages.Select(m => m.Id)), Builders <OutboxMessage> .Update.Set(m => m.ProcessedAt, DateTime.UtcNow)); }