public override async Task Invoke(IOutgoingPhysicalMessageContext context, Func <Task> next) { if (!DedupePipelineState.TryGet(context, out var dedupePipelineState)) { await next(); return; } var connectionTask = connectionBuilder(CancellationToken.None); if (context.Extensions.TryGet(out TransportTransaction _)) { throw new NotSupportedException("Deduplication is currently designed to be used from outside the NServiceBus pipeline. For example to dedup messages being sent from inside a web service endpoint."); } var messageId = GetMessageId(context); var transportTransaction = new TransportTransaction(); context.Extensions.Set(transportTransaction); await using var connection = await connectionTask; await using var transaction = (SqlTransaction) await connection.BeginTransactionAsync(); transportTransaction.Set(connection); transportTransaction.Set(transaction); var dedupeManager = new DedupeManager(transaction, table); var writeResult = await dedupeManager.WriteDedupRecord(messageId, dedupePipelineState.Context); dedupePipelineState.DedupeOutcome = writeResult.DedupeOutcome; dedupePipelineState.Context = writeResult.Context; if (dedupePipelineState.DedupeOutcome == DedupeOutcome.Deduplicated) { logger.Info($"Message deduplicated. MessageId: {messageId}"); return; } await next(); var commitResult = await dedupeManager.CommitWithDedupCheck(messageId, dedupePipelineState.Context); dedupePipelineState.DedupeOutcome = commitResult.DedupeOutcome; dedupePipelineState.Context = commitResult.Context; if (commitResult.DedupeOutcome == DedupeOutcome.Deduplicated) { logger.Info($"Message deduplicated. MessageId: {messageId}"); } }
static async Task <DedupeResult> InnerSendWithDedupe(IMessageSession session, object message, Guid messageId, SendOptions options, string?context) { var pipelineState = new DedupePipelineState { Context = context }; DedupePipelineState.Set(options, pipelineState); options.SetMessageId(messageId.ToString()); await session.Send(message, options); return(new( dedupeOutcome : pipelineState.DedupeOutcome, context : pipelineState.Context )); }
public static void Set(SendOptions options, DedupePipelineState state) { options.GetExtensions().Set(state); }