Я использую шаблон запроса-ответа, чтобы убедиться, что правильный рабочий процесс выполняется последовательно. У меня есть 3 проекта
Order.API
OrderPayment.API
OrderConfirmation.API
Он правильно выполняет каждого потребителя, но после этого, после последнего кода последнего потребителя, он дает мне загрузка при чванстве и каждый раз выдает ошибку времени ожидания запроса. , он не возвращает ответ обратно в контроллер независимо от того, успешно ли выполнена работа или нет, он ожидает ожидания, а затем ответом является ошибка таймаута запроса.
Код
Потребитель в OrderPayment.API
public class PaymentConsumer : IConsumer
{
public async Task Consume(ConsumeContext context)
{
Console.WriteLine($"Payment processed for OrderId: {context.Message.OrderId}");
await context.Send(new OrderConfirmed { OrderId = context.Message.OrderId });
}
}
и в Program.cs
builder.Services.AddMassTransit(x =>
{
x.AddConsumer
();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h => { h.Username("guest"); h.Password("guest");});
cfg.ConfigureEndpoints(context);
});
});
В OrderConfirmation.API
public class ConfirmationConsumer : IConsumer
{
public async Task Consume(ConsumeContext context)
{
Console.WriteLine($"Order {context.Message.OrderId} has been confirmed.");
await Task.CompletedTask;
}
}
и в Program.cs
builder.Services.AddMassTransit(x =>
{
x.AddConsumer();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h => { h.Username("guest"); h.Password("guest");});
cfg.ConfigureEndpoints(context);
});
});
Общие модели и состояния и события
namespace SharedModels.OrderProcessModels
{
// Event when an order is created
public class OrderCreated
{
public Guid OrderId { get; set; }
}
// Response for Order creation
public class OrderCreatedResponse
{
public Guid OrderId { get; set; }
public string Status { get; set; } = "OrderCreated";
}
// Event when the payment is processed
public class PaymentProcessed
{
public Guid OrderId { get; set; }
}
// Response after Payment is processed
public class PaymentProcessedResponse
{
public Guid OrderId { get; set; }
public string Status { get; set; } = "PaymentProcessed";
}
// Event when the order is confirmed
public class OrderConfirmed
{
public Guid OrderId { get; set; }
}
// Response for order confirmation
public class OrderConfirmedResponse
{
public Guid OrderId { get; set; }
public string Status { get; set; } = "OrderConfirmed";
}
// State object that tracks the lifecycle of an order
public class OrderState : SagaStateMachineInstance
{
public Uri ResponseAddress { get; set; }
public Guid RequestId { get; set; } // Optionally store RequestId for correlation
public Guid CorrelationId { get; set; } // Unique identifier for Saga instance
public Guid OrderId { get; set; } // Order identifier
public State CurrentState { get; set; } // Current state of the order in saga
public DateTime? CreatedAt { get; set; } // When the order was created
public DateTime? PaymentAt { get; set; } // When the payment was processed
public DateTime? ConfirmedAt { get; set; } // When the order was confirmed
}
}
Теперь я создал Order.API OrderStateMachine.cs
public class OrderStateMachine : MassTransitStateMachine
{
public State PaymentProcessed { get; private set; }
public State OrderConfirmed { get; private set; }
public Event OrderCreatedEvent { get; private set; }
public Event
PaymentProcessedEvent { get; private set; }
public Event OrderConfirmedEvent { get; private set; }
public OrderStateMachine()
{
InstanceState(x => x.CurrentState);
// Correlate Events with Saga Instance by OrderId
Event(() => OrderCreatedEvent, x => x.CorrelateById(c => c.Message.OrderId));
Event(() => PaymentProcessedEvent, x => x.CorrelateById(c => c.Message.OrderId));
Event(() => OrderConfirmedEvent, x => x.CorrelateById(c => c.Message.OrderId));
// Initial State -> PaymentProcessed
Initially(
When(OrderCreatedEvent)
.Then(context =>
{
context.Saga.OrderId = context.Message.OrderId; // Save the order ID
context.Saga.CreatedAt = DateTime.UtcNow; // Set the creation timestamp
Console.WriteLine("Order created, transitioning to PaymentProcessed...");
})
.TransitionTo(PaymentProcessed) // Move to PaymentProcessed state
.Publish(context => new PaymentProcessed
{
OrderId = context.Saga.OrderId
})
);
// PaymentProcessed State -> OrderConfirmed
During(PaymentProcessed,
When(PaymentProcessedEvent)
.Then(context =>
{
context.Saga.PaymentAt = DateTime.UtcNow; // Set payment timestamp
Console.WriteLine("Payment processed, transitioning to OrderConfirmed...");
})
.TransitionTo(OrderConfirmed) // Move to OrderConfirmed state
.Publish(context => new OrderConfirmed
{
OrderId = context.Saga.OrderId
})
);
//Final State -> Complete Saga
During(OrderConfirmed,
When(OrderConfirmedEvent)
.Then(context =>
{
context.Saga.ConfirmedAt = DateTime.UtcNow; // Set confirmation timestamp
Console.WriteLine($"Order confirmed for OrderId: {context.Saga.OrderId}");
})
.Finalize() // Finalize saga after order is confirmed
);
SetCompletedWhenFinalized();
}
}
OrderController.cs в Order.API
namespace Order.API.Controllers
{
[ApiController]
[Route("api")]
public class OrderController : ControllerBase
{
private readonly IRequestClient _requestClient; //bcz wait for the first one, then execute further.
public OrderController(IRequestClient requestClient)
{
_requestClient = requestClient;
}
[HttpPost("PlaceOrder")]
public async Task PlaceOrder([FromBody] CreateOrderModel model)
{
try
{
var status = await _requestClient.GetResponse(new OrderCreated { OrderId = orderId });
if (status != null)
{
return Ok(new { OrderId = orderId, Status = "Order confirmed" });
}
else
{
return StatusCode(500, "Order processing failed.");
}
}
catch (Exception e)
{
return StatusCode(504, "Timeout waiting for the order confirmation.");
}
}
}
public class CreateOrderModel
{
public string OrderId { get; set; }
public string CustomerName { get; set; }
public double Amount { get; set; }
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... -consumers
Как я могу получить ответ обратно в свой контроллер заказов после выполнения всех потребителей с использованием конечног ⇐ C#
Место общения программистов C#
1727177718
Anonymous
Я использую шаблон запроса-ответа, чтобы убедиться, что правильный рабочий процесс выполняется последовательно. У меня есть 3 проекта
[b]Order.API
OrderPayment.API
OrderConfirmation.API[/b]
Он правильно выполняет каждого потребителя, но после этого, после последнего кода последнего потребителя, он дает мне загрузка при чванстве и каждый раз выдает ошибку времени ожидания запроса. , он не возвращает ответ обратно в контроллер независимо от того, успешно ли выполнена работа или нет, он ожидает ожидания, а затем ответом является ошибка таймаута запроса.
Код
Потребитель в [b]OrderPayment.API[/b]
public class PaymentConsumer : IConsumer
{
public async Task Consume(ConsumeContext context)
{
Console.WriteLine($"Payment processed for OrderId: {context.Message.OrderId}");
await context.Send(new OrderConfirmed { OrderId = context.Message.OrderId });
}
}
и в [b]Program.cs[/b]
builder.Services.AddMassTransit(x =>
{
x.AddConsumer
();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h => { h.Username("guest"); h.Password("guest");});
cfg.ConfigureEndpoints(context);
});
});
В [b]OrderConfirmation.API[/b]
public class ConfirmationConsumer : IConsumer
{
public async Task Consume(ConsumeContext context)
{
Console.WriteLine($"Order {context.Message.OrderId} has been confirmed.");
await Task.CompletedTask;
}
}
и в [b]Program.cs[/b]
builder.Services.AddMassTransit(x =>
{
x.AddConsumer();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h => { h.Username("guest"); h.Password("guest");});
cfg.ConfigureEndpoints(context);
});
});
Общие [b]модели[/b] и [b]состояния[/b] и [b]события[/b]
namespace SharedModels.OrderProcessModels
{
// Event when an order is created
public class OrderCreated
{
public Guid OrderId { get; set; }
}
// Response for Order creation
public class OrderCreatedResponse
{
public Guid OrderId { get; set; }
public string Status { get; set; } = "OrderCreated";
}
// Event when the payment is processed
public class PaymentProcessed
{
public Guid OrderId { get; set; }
}
// Response after Payment is processed
public class PaymentProcessedResponse
{
public Guid OrderId { get; set; }
public string Status { get; set; } = "PaymentProcessed";
}
// Event when the order is confirmed
public class OrderConfirmed
{
public Guid OrderId { get; set; }
}
// Response for order confirmation
public class OrderConfirmedResponse
{
public Guid OrderId { get; set; }
public string Status { get; set; } = "OrderConfirmed";
}
// State object that tracks the lifecycle of an order
public class OrderState : SagaStateMachineInstance
{
public Uri ResponseAddress { get; set; }
public Guid RequestId { get; set; } // Optionally store RequestId for correlation
public Guid CorrelationId { get; set; } // Unique identifier for Saga instance
public Guid OrderId { get; set; } // Order identifier
public State CurrentState { get; set; } // Current state of the order in saga
public DateTime? CreatedAt { get; set; } // When the order was created
public DateTime? PaymentAt { get; set; } // When the payment was processed
public DateTime? ConfirmedAt { get; set; } // When the order was confirmed
}
}
Теперь я создал [b]Order.API[/b] [b]OrderStateMachine.cs[/b]
public class OrderStateMachine : MassTransitStateMachine
{
public State PaymentProcessed { get; private set; }
public State OrderConfirmed { get; private set; }
public Event OrderCreatedEvent { get; private set; }
public Event
PaymentProcessedEvent { get; private set; }
public Event OrderConfirmedEvent { get; private set; }
public OrderStateMachine()
{
InstanceState(x => x.CurrentState);
// Correlate Events with Saga Instance by OrderId
Event(() => OrderCreatedEvent, x => x.CorrelateById(c => c.Message.OrderId));
Event(() => PaymentProcessedEvent, x => x.CorrelateById(c => c.Message.OrderId));
Event(() => OrderConfirmedEvent, x => x.CorrelateById(c => c.Message.OrderId));
// Initial State -> PaymentProcessed
Initially(
When(OrderCreatedEvent)
.Then(context =>
{
context.Saga.OrderId = context.Message.OrderId; // Save the order ID
context.Saga.CreatedAt = DateTime.UtcNow; // Set the creation timestamp
Console.WriteLine("Order created, transitioning to PaymentProcessed...");
})
.TransitionTo(PaymentProcessed) // Move to PaymentProcessed state
.Publish(context => new PaymentProcessed
{
OrderId = context.Saga.OrderId
})
);
// PaymentProcessed State -> OrderConfirmed
During(PaymentProcessed,
When(PaymentProcessedEvent)
.Then(context =>
{
context.Saga.PaymentAt = DateTime.UtcNow; // Set payment timestamp
Console.WriteLine("Payment processed, transitioning to OrderConfirmed...");
})
.TransitionTo(OrderConfirmed) // Move to OrderConfirmed state
.Publish(context => new OrderConfirmed
{
OrderId = context.Saga.OrderId
})
);
//Final State -> Complete Saga
During(OrderConfirmed,
When(OrderConfirmedEvent)
.Then(context =>
{
context.Saga.ConfirmedAt = DateTime.UtcNow; // Set confirmation timestamp
Console.WriteLine($"Order confirmed for OrderId: {context.Saga.OrderId}");
})
.Finalize() // Finalize saga after order is confirmed
);
SetCompletedWhenFinalized();
}
}
[b]OrderController.cs[/b] в [b]Order.API[/b]
namespace Order.API.Controllers
{
[ApiController]
[Route("api")]
public class OrderController : ControllerBase
{
private readonly IRequestClient _requestClient; //bcz wait for the first one, then execute further.
public OrderController(IRequestClient requestClient)
{
_requestClient = requestClient;
}
[HttpPost("PlaceOrder")]
public async Task PlaceOrder([FromBody] CreateOrderModel model)
{
try
{
var status = await _requestClient.GetResponse(new OrderCreated { OrderId = orderId });
if (status != null)
{
return Ok(new { OrderId = orderId, Status = "Order confirmed" });
}
else
{
return StatusCode(500, "Order processing failed.");
}
}
catch (Exception e)
{
return StatusCode(504, "Timeout waiting for the order confirmation.");
}
}
}
public class CreateOrderModel
{
public string OrderId { get; set; }
public string CustomerName { get; set; }
public double Amount { get; set; }
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79018419/how-can-i-get-response-back-in-my-order-controller-after-executes-all-consumers[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия