protected override async Task DeadLetter(MessageReadResult receiveResult, SqlConnection connection, SqlTransaction transaction) { using (var errorConnection = await connectionFactory.OpenNewConnection(ErrorQueue.TransportAddress).ConfigureAwait(false)) { await ErrorQueue.DeadLetter(receiveResult.PoisonMessage, errorConnection, null).ConfigureAwait(false); } }
public override async Task ProcessMessage(CancellationTokenSource stopBatchCancellationTokenSource, CancellationToken cancellationToken = default) { Message message = null; var context = new ContextBag(); try { using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions, TransactionScopeAsyncFlowOption.Enabled)) using (var connection = await connectionFactory.OpenNewConnection(cancellationToken).ConfigureAwait(false)) { var receiveResult = await InputQueue.TryReceive(connection, null, cancellationToken).ConfigureAwait(false); if (receiveResult == MessageReadResult.NoMessage) { stopBatchCancellationTokenSource.Cancel(); return; } if (receiveResult.IsPoison) { await ErrorQueue.DeadLetter(receiveResult.PoisonMessage, connection, null, cancellationToken).ConfigureAwait(false); scope.Complete(); return; } if (await TryHandleDelayedMessage(receiveResult.Message, connection, null, cancellationToken).ConfigureAwait(false)) { scope.Complete(); return; } message = receiveResult.Message; connection.Close(); if (!await TryProcess(receiveResult.Message, PrepareTransportTransaction(), context, cancellationToken).ConfigureAwait(false)) { return; } scope.Complete(); } failureInfoStorage.ClearFailureInfoForMessage(message.TransportId); } catch (Exception ex) when(!ex.IsCausedBy(cancellationToken)) { if (message == null) { throw; } failureInfoStorage.RecordFailureInfoForMessage(message.TransportId, ex, context); } }
public override async Task ProcessMessage(CancellationTokenSource stopBatchCancellationTokenSource, CancellationToken cancellationToken = default) { Message message = null; var context = new ContextBag(); try { using (var connection = await connectionFactory.OpenNewConnection(cancellationToken).ConfigureAwait(false)) using (var transaction = connection.BeginTransaction(isolationLevel)) { var receiveResult = await InputQueue.TryReceive(connection, transaction, cancellationToken).ConfigureAwait(false); if (receiveResult == MessageReadResult.NoMessage) { stopBatchCancellationTokenSource.Cancel(); return; } if (receiveResult.IsPoison) { await ErrorQueue.DeadLetter(receiveResult.PoisonMessage, connection, transaction, cancellationToken).ConfigureAwait(false); transaction.Commit(); return; } if (await TryHandleDelayedMessage(receiveResult.Message, connection, transaction, cancellationToken).ConfigureAwait(false)) { transaction.Commit(); return; } message = receiveResult.Message; if (!await TryProcess(receiveResult.Message, PrepareTransportTransaction(connection, transaction), context, cancellationToken).ConfigureAwait(false)) { transaction.Rollback(); return; } transaction.Commit(); } failureInfoStorage.ClearFailureInfoForMessage(message.TransportId); } catch (Exception ex) when(!ex.IsCausedBy(cancellationToken)) { if (message == null) { throw; } failureInfoStorage.RecordFailureInfoForMessage(message.TransportId, ex, context); } }
public override async Task ProcessMessage(CancellationTokenSource stopBatchCancellationTokenSource, CancellationToken cancellationToken = default) { using (var connection = await connectionFactory.OpenNewConnection(cancellationToken).ConfigureAwait(false)) { MessageReadResult receiveResult; using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)) { receiveResult = await InputQueue.TryReceive(connection, transaction, cancellationToken).ConfigureAwait(false); if (receiveResult == MessageReadResult.NoMessage) { stopBatchCancellationTokenSource.Cancel(); return; } if (receiveResult.IsPoison) { await ErrorQueue.DeadLetter(receiveResult.PoisonMessage, connection, transaction, cancellationToken).ConfigureAwait(false); transaction.Commit(); return; } if (await TryHandleDelayedMessage(receiveResult.Message, connection, transaction, cancellationToken).ConfigureAwait(false)) { transaction.Commit(); return; } transaction.Commit(); } var context = new ContextBag(); var transportTransaction = new TransportTransaction(); transportTransaction.Set(SettingsKeys.TransportTransactionSqlConnectionKey, connection); try { await TryHandleMessage(receiveResult.Message, transportTransaction, context, cancellationToken).ConfigureAwait(false); } catch (Exception ex) when(!ex.IsCausedBy(cancellationToken)) { // Since this is TransactionMode.None, we don't care whether error handling says handled or retry. Message is gone either way. _ = await HandleError(ex, receiveResult.Message, transportTransaction, 1, context, cancellationToken).ConfigureAwait(false); } } }