public IEnumerable <OutboxMessage> HydrateOutboxMessages(DbDataReader reader) { List <OutboxMessage> outboxMessages = new List <OutboxMessage>(); while (reader.Read()) { var id = reader.GetGuid(0); var priorityDateUtc = reader.GetDateTime(1); var type = reader.GetString(2); string endpoint = null; if (!reader.IsDBNull(3)) { endpoint = reader.GetString(3); } var tryCount = reader.GetInt32(4); var status = reader.GetInt32(5); DateTime?expiresAtUtc = null; if (!reader.IsDBNull(6)) { expiresAtUtc = reader.GetDateTime(6); } var createdAtUtc = reader.GetDateTime(7); var dataId = reader.GetGuid(8); var data = (byte[])reader.GetValue(9); string metaData = null; if (!reader.IsDBNull(10)) { metaData = reader.GetString(10); } var outboxMessage = new OutboxMessage(type, data, metaData, priorityDateUtc, endpoint, false, expiresAtUtc, id) { TryCount = tryCount, Status = status, CreatedAtUtc = createdAtUtc, }; outboxMessages.Add(outboxMessage); } return(outboxMessages); }
private async Task _relay(OutboxMessage outboxMessage, Dispatcher dispatcher, bool isTransient = false) { if (!_isValidForRelay(outboxMessage)) { MarkAsFailure(outboxMessage, permanent: true); } else { try { var metaData = outboxMessage.MessageData.MetaData != null?JsonConvert.DeserializeObject <MessageMetaData>(outboxMessage.MessageData.MetaData) : null; //await relayCallback(outboxMessage.Type, outboxMessage.MessageData.Data, metaData, outboxMessage.Endpoint); await dispatcher.Invoke(outboxMessage.Type, outboxMessage.MessageData.Data, metaData, outboxMessage.Endpoint, isTransient); MarkAsComplete(outboxMessage); } catch (Exception ex) { MarkAsFailure(outboxMessage); _log.LogError(ex, "Error publishing Outbox Event Id: {id} Type: {type} Tries: {retryCount}", outboxMessage.Id, outboxMessage.Type, outboxMessage.TryCount); } }//else }
private void MarkAsComplete(OutboxMessage outboxMessage) { try { using (var conn = _dbConnection.Get()) using (IDbCommand command = conn.CreateCommand()) { conn.Open(); command.CommandText = "update dbo.OutboxMessages SET [Status] = 2 where Id = @Id"; SqlParameter parameter = new SqlParameter("@Id", outboxMessage.Id) { SqlDbType = SqlDbType.UniqueIdentifier, Direction = ParameterDirection.Input, }; command.Parameters.Add(parameter); int rows = command.ExecuteNonQuery(); } } catch (Exception ex) { _log.LogError(ex, "Exception marking outbox message complete Message Id: {id} Type: {type} Tries: {retryCount}", outboxMessage.Id, outboxMessage.Type, outboxMessage.TryCount); throw; } }
private Task _addToContext(string messageTypeIdentifier, byte[] message, MessageMetaData meta, IEndpoint endpoint = null, OutboxDispatchOptions options = null) { options = options ?? new OutboxDispatchOptions(); double delayInSeconds = 0; //send immediately bool skipTransient = _outbox.DisableTransientDispatch; if (!skipTransient) { skipTransient = options.SkipTransientDispatch;//check at the message level } if (options.Delay.HasValue) { delayInSeconds = options.Delay.Value.TotalSeconds; } var priorityDateUtc = DateTime.UtcNow.AddSeconds(delayInSeconds); var outboxMessage = new OutboxMessage( messageTypeIdentifier, message, meta != null ? JsonConvert.SerializeObject(meta) : null, priorityDateUtc, endpoint?.Name, skipTransient, options.ExpiresAtUtc); //add the message for persistance with the dbcontext _dbContext.Add(outboxMessage); if (!outboxMessage.SkipTransientDispatch) { this._transientMessageQueue.Enqueue(outboxMessage); } return(Task.CompletedTask); }