Why does my MassTransit Fault Consumer not get called?

孤街醉人 提交于 2021-02-10 14:38:01

问题


I am using MassTransit 7.1.4.0 together with RabbitMQ 3.8.7.

I have a consumer which simply throws an exception, and I have a fault consumer which Console.WriteLine the fact that a fault occurred.

The fault consumer is not called. I also tried using a fault consumer definition. Also that does not work.

Below is the entire program.

    using System;
    using System.Threading.Tasks;
    using GreenPipes;
    using MassTransit;
    using MassTransit.ConsumeConfigurators;
    using MassTransit.Definition;
    using Microsoft.Extensions.DependencyInjection;

    namespace FaultConsumer
    {
      class Program
      {
        static async Task Main(string[] args)
        {
          Console.WriteLine("Hello Fault Consumer!");

          var services = new ServiceCollection();

          services.AddMassTransit(x =>
          {

            x.AddConsumer<MyConsumer>(typeof(MyConsumerDefinition));
            x.AddConsumer<MyFaultConsumer>();//typeof(MyFaultConsumerDefinition));
            x.SetKebabCaseEndpointNameFormatter();
            x.UsingRabbitMq((context, cfg) =>
            {
              cfg.Host("rabbitmq://localhost");
              cfg.ConfigureEndpoints(context);
            });

          });

          var serviceProvider = services.BuildServiceProvider();
          var bus = serviceProvider.GetRequiredService<IBusControl>();

          await bus.StartAsync();
          await bus.Publish(new SubmitOrder() { DateTimeStamp = DateTime.Now });

          Console.WriteLine("Press any key to exit");
          await Task.Run(() => Console.ReadKey());

          await bus.StopAsync();

        }
      }

      class SubmitOrder
      {
        public DateTime DateTimeStamp { get; set; }
      }

      class MyConsumer : IConsumer<SubmitOrder>
      {
        public async Task Consume(ConsumeContext<SubmitOrder> context)
        {
          Console.WriteLine($"Attempting to consume {context.GetRetryCount()} {context.GetRetryAttempt()}");
          throw new Exception(context.GetRetryCount().ToString());
        }
      }

      class MyConsumerDefinition : ConsumerDefinition<MyConsumer>
      {
        public MyConsumerDefinition()
        {
          EndpointName = "order-service-202102081221";

          ConcurrentMessageLimit = 8;
        }

        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
              IConsumerConfigurator<MyConsumer> consumerConfigurator)
        {
          //endpointConfigurator.UseMessageRetry(r => r.Intervals(100, 200, 500, 800, 1000));
          endpointConfigurator.UseMessageRetry(r => r.Immediate(5));

          endpointConfigurator.UseInMemoryOutbox();
        }
      }

      class MyFaultConsumer : IConsumer<Fault<MyConsumer>>
      {
        public async Task Consume(ConsumeContext<Fault<MyConsumer>> context)
        {
          Console.WriteLine("Fault");
          await Task.CompletedTask;
        }

      }

      //   class MyFaultConsumerDefinition : ConsumerDefinition<MyFaultConsumer>
      //   {
      //     public MyFaultConsumerDefinition()
      //     {
      //       // override the default endpoint name
      //       EndpointName = "order-service-faults-202102081221";

      //       // limit the number of messages consumed concurrently
      //       // this applies to the consumer only, not the endpoint
      //       ConcurrentMessageLimit = 8;
      //     }

      //     protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
      //           IConsumerConfigurator<MyFaultConsumer> consumerConfigurator)
      //     {
      //       // configure message retry with millisecond intervals
      //       endpointConfigurator.UseMessageRetry(r => r.Intervals(100, 200, 500, 800, 1000));

      //       // use the outbox to prevent duplicate events from being published
      //       endpointConfigurator.UseInMemoryOutbox();
      //     }
      //   }
    }

回答1:


Faults are published based on message type, not consumer type.

Your fault consumer should be consuming Fault<SubmitOrder>.

class MyFaultConsumer : 
    IConsumer<Fault<SubmitOrder>>
{
    public Task Consume(ConsumeContext<Fault<SubmitOrder>> context)
    {
        Console.WriteLine("Fault");

        return Task.CompletedTask;
    }
}


来源:https://stackoverflow.com/questions/66101730/why-does-my-masstransit-fault-consumer-not-get-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!