Если у меня много операций, это приводит к блокировке ресурсов или истечению времени ожидания?
Вот мой сценарий:
У меня есть контроллер API, который отправляет запрос Order потребителю;Я использую шаблон запроса / ответа, чтобы получить ErrorMessage свойство от потребителя и основываться на ответе этого свойства обратно, если оно равно null, я бы хотел вернуть OK()
, в противном случае вернуть BadRequest
или Ok
, но с таким сообщением, как: Продукт отсутствует на складе для уведомления клиента .
У моего потребителя есть сборкабланк маршрутизации, который имеет 2 действия:
- CreateOrderActivity : создает заказ с деталями заказа.
ReserveProductActivity :Что уменьшает количество товара на складе, if product quantity < 0
Я опубликую сообщение с ErrorMessage обратно к потребителю и компенсирую предыдущую активность.
public async Task Consume(ConsumeContext<ProcessOrder> context)
{
try
{
if (!string.IsNullOrEmpty(context.Message.ErrorMessage))
{
await context.RespondAsync<OrderSubmitted>(new
{
context.Message.OrderId,
context.Message.ErrorMessage
});
return;
}
RoutingSlipBuilder builder = new RoutingSlipBuilder(context.Message.OrderId);
// get configs
var settings = new Settings(_configuration);
// Add activities
builder.AddActivity(settings.CreateOrderActivityName, settings.CreateOrderExecuteAddress);
builder.SetVariables(new { context.Message.OrderId, context.Message.Address, context.Message.CreatedDate, context.Message.OrderDetails });
builder.AddActivity(settings.ReserveProductActivityName, settings.ReserveProductExecuteAddress);
builder.SetVariables(new { context.Message.OrderDetails });
await context.Execute(builder.Build());
await context.RespondAsync<OrderSubmitted>(new
{
context.Message.OrderId
});
}
catch (Exception ex)
{
_log.LogError("Can not create Order {OrderId}", context.Message.OrderId);
throw new Exception(ex.Message);
}
}
Код для ReserveProductActivity:
public async Task<ExecutionResult> Execute(ExecuteContext<ReserveProductArguments> context)
{
var orderDetails = context.Arguments.OrderDetails;
foreach (var orderDetail in orderDetails)
{
var product = await _productRepository.GetByProductId(orderDetail.ProductId);
if (product == null) continue;
var quantity = product.SetQuantity(product.QuantityInStock - orderDetail.Quantity);
if (quantity < 0)
{
var errorMessage = "Out of stock.";
await context.Publish<ProcessOrder>(new
{
ErrorMessage = errorMessage
});
throw new RoutingSlipException(errorMessage);
}
await _productRepository.Update(product);
}
return context.Completed(new Log(orderDetails.Select(x => x.ProductId).ToList()));
}
Эта строка кода в потребительском методе ожидает контекст. Execute (builder.Build ())
Сначала я подумал, что он создаст квитанцию и выполнит все действияПрежде чем перейти к следующей строке, но это не так. Вместо этого он сразу переходит к следующей строке кода (которая отвечает обратно контроллеру), а затем после выполнения действий, а это не то, что мне нужно. Мне нужно сначала проверить количество продукта во 2-м действии и на основе этого возврата вернуться к контроллеру.
(В текущем случае он всегда отвечает сначала контроллеру - строка после buider.Buid()
, а затем, если quantity < 0
, он по-прежнему переходит к самому первому условию метода потребления, но так как он уже отвечает, я не могу вызвать ответ внутри этого оператора if снова.
Короче говоря, если продукт все еще доступен во втором задании, я могу отправить ответ как обычно (который выполняет код после context.Execute(builder.Build())
, но если quantity < 0
- чтоЯ публикую обратно на потребительский метод с ErrorMessage , я бы хотел, чтобы он перешел к самому первому, если условие метода Consume (if(!string.IsNullOrEmpty(context.Message.ErrorMessage)) ...
) и основано на ErrorMessage уведомить клиента.
Что-то не так с этим подходом? Как мне добиться чего-то подобного?
Спасибо