MassTransit - prevent a message going to the RMQ skipped queue, when a filter is used

ripe_bananas :

I am using MassTransit with RabbitMQ. Following the exmaple on the official documentation page for custom middleware, I am trying to create a filter on the message consumption pipeline that will filter-out some messages based on a certain condition. My filter looks like this:

public class MyCustomFilter<T> : IFilter<T>
    where T : class, ConsumeContext
{
    public void Probe(ProbeContext context) { }

    public async Task Send(T context, IPipe<T> next)
    {
        if (/* certain condition */)
        {
            await next.Send(context);
        }
    }
}

The problem is that when the message is not passed down the pipeline (i.e. await next.Send(context) is not called), the message ends in the _skipped consumer RabbitMQ queue. Is there a way to prevent the message from going in that queue?

Alexey Zimarev :

The skipped (dead-letter) queue gets the message by the DeadLetterFilter invocation. Here is the code:

async Task IFilter<ReceiveContext>.Send(ReceiveContext context, IPipe<ReceiveContext> next)
{
    await next.Send(context).ConfigureAwait(false);

    if (context.IsDelivered || context.IsFaulted)
        return;

    context.LogSkipped();

    await _deadLetterPipe.Send(context).ConfigureAwait(false);
}

So, you could imagine that if the context has IsDelivered or IsFaulted set to true, your messages won't end up in the dead-letter queue.

If you throw in the filter, your messages end up in the poison (error) queue instead, so I guess that's not an option.

You can simulate your messages being delivered by doing something like this for filtered messages in your filter:

public Task Send(T context, IPipe<T> next)
    => condition
        ? next.Send(context)
        : context.NotifyConsumed(context as ConsumeContext<MyMessage>, TimeSpan.Zero, "Filtered");

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=293660&siteId=1