Почему метод Compensate не вызывается, когда потребитель выдал исключение в MassTransit RouterSlip - PullRequest
0 голосов
/ 12 июля 2020

Я построил маршрутизатор внутри конечного автомата саги:

var builder = new RoutingSlipBuilder(NewId.NextGuid());
            var submitOrderUrl = QueueNames.GetActivityUri(nameof(SubmitOrderActivity));
            builder.AddActivity("SubmitOrder", submitOrderUrl, new
            {
                context.Message.OrderId
            });;
            builder.AddActivity("Payment", QueueNames.GetActivityUri(nameof(PaymentActivity)), new {
                context.Message.OrderId,
                context.Message.CustomerId,
                context.Message.Credit
            });
           
            builder.AddActivity("TakeProduct", QueueNames.GetActivityUri(nameof(TakeProductActivity)), new
            {
                context.Message.OrderId,
                Baskets
            });
            builder.AddVariable("OrderId", context.Message.OrderId);
            var routingSlip = builder.Build();
            await context.Execute(routingSlip);

И у меня есть действие TakeProductActivity: publi c class TakeProductActivity: IActivity : ...

 public async Task<ExecutionResult> Execute(ExecuteContext<TakeProductArgument> context)
        {
            logger.LogInformation($"Take Product Courier called for order {context.Arguments.OrderId}");            
            var uri = QueueNames.GetMessageUri(nameof(TakeProductTransactionMessage));
            var sendEndpoint = await context.GetSendEndpoint(uri);
            await sendEndpoint.Send<TakeProductTransactionMessage>(new
            {
                ProductBaskets = context.Arguments.Baskets                
            });
             
            return context.Completed(new { Baskets = context.Arguments.Baskets, OrderId=context.Arguments.OrderId });
        }

Когда я использую метод sendEndpoint.Send () (запустить и забыть), когда в службе возникло исключение, метод компенсации не активируется автоматически, но когда я использую requestClient. GetResponse (запрос / ответ) для вызова службы, при возникновении исключения автоматически вызывается метод компенсации. и в PaymentConsumer, когда генерируется исключение, это должны быть методы компенсации для вызываемого платежа, но это не так!

///this class has implemented in another micro-service hosted separate process:
public class TakeProductTransactionConsumer : IConsumer<TakeProductTransactionMessage>
....
 public async Task Consume(ConsumeContext<TakeProductTransactionMessage> context)
        {
            if(context.Message.ProductBaskets.Count>0)
             { 
                    throw new Exception("Process Failed!");
             }
            logger.LogInformation($"Take product called ");
         
            Dictionary<int, int> productCounts = new Dictionary<int, int>();
            foreach (var item in context.Message.ProductBaskets)
            {
                productCounts.Add(item.ProductId, item.Count);
            }
            var products = await productService.TakeProducts(productCounts);
            await publishEndpoint.Publish<ProductsUpdatedEvent>(new
            {
                ProductUpdatedEvents = products.Select(p =>new { ProductId = p.Id,p.Price,p.Count}).ToList()
            });
           
            
        }

проблема в том, что MassTransit не может получить исключение из rabbitMQ и автоматически вызвать методы компенсации. Как мне сказать MassTransit вызвать компенсацию, когда исключение выбрасывается в действиях с ошибкой маршрутизатора

1 Ответ

1 голос
/ 12 июля 2020

Если в вашем действии Take Product используется «Отправить и запустить и забыть в службу продукта take», и эта служба выдает исключение, действие никогда не узнает об этом, потому что оно уже выполнено. Запустить и забыть - это просто, никаких исключений в целевой службе не наблюдается.

Если вы хотите, чтобы действие продукта take завершалось неудачно, когда сервис продукта take выдает исключение, вам нужно использовать запрос / ответ для соблюдайте исключение из службы.

...