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}");
        }
    }
Пример #2
0
    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
                   ));
    }
Пример #3
0
 public static void Set(SendOptions options, DedupePipelineState state)
 {
     options.GetExtensions().Set(state);
 }