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?
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");