Mikh Dany
Mikh Dany

Reputation: 13

SAGA event not returning to main controller, its going for long loading resulted in request timeout. Maybe mistake in SagaCompletionNotification event

When debugger reached to this point, it comes in ThenAsync, and after that, it is not return to main controller (BurgerController), it is going to long loading that result in request timeout. I think something wrong or not returning from SagaCompletionNotification.

During(FinishedCooking,
  When(BurgerCookerFinishedCookingEvent)
  .ThenAsync(async x =>
  {
       //should final response back to Main controller
      await x.Publish(new SagaCompletionNotification
      {
          CorrelationId = x.Saga.CorrelationId
      });
  })
  .TransitionTo(Completed)
  .Finalize()
  );

Complete SagaStateMachine

public class BurgerCookStateMachine : MassTransitStateMachine<BurgerCookerState>
{
    public State Ordered { get; private set; }
    public State BeginCooking { get; private set; }
    public State FinishedCooking { get; private set; }
    public State Completed { get; private set; }

    public Event<BurgerCookerOrderedEvent> BurgerCookerOrderedEvent { get; private set; }
    public Event<BurgerCookerBeginCookingEvent> BurgerCookerBeginCookingEvent { get; private set; }
    public Event<BurgerCookerFinishedCookingEvent> BurgerCookerFinishedCookingEvent { get; private set; }

    public BurgerCookStateMachine()
    {
        InstanceState(x => x.CurrentState);

        Event(() => BurgerCookerOrderedEvent, x => x.CorrelateById(context => context.Message.CorrelationId));
        Event(() => BurgerCookerBeginCookingEvent, x => x.CorrelateById(context => context.Message.CorrelationId));
        Event(() => BurgerCookerFinishedCookingEvent, x => x.CorrelateById(context => context.Message.CorrelationId));

        Initially(
            When(BurgerCookerOrderedEvent)
            .ThenAsync(async x =>
            {
                x.Saga.CustomerName = x.Message.CustomerName;
            })
            .PublishAsync(async x => new BurgerCookerBeginCookingEvent()
            {
                CorrelationId = x.Saga.CorrelationId,
                CookTemp = x.Saga.CookTemp, //check x.message.cookTemp
            })
            .TransitionTo(BeginCooking)
            ); 

        During(BeginCooking,
          When(BurgerCookerBeginCookingEvent)
          .ThenAsync(async x => 
          { 
              //make more functionality
          })
          .PublishAsync(async x=>new CookBurger
          {
              CookTemp = "90Degree",
              CorrelationId = x.Saga.CorrelationId
          })
          .TransitionTo(FinishedCooking));

        During(FinishedCooking,
          When(BurgerCookerFinishedCookingEvent)
          .ThenAsync(async x =>
          {
               //should final response back to Main controller
              await x.Publish(new SagaCompletionNotification
              {
                  CorrelationId = x.Saga.CorrelationId
              });
          })
          .TransitionTo(Completed)
          .Finalize()
          );
        SetCompletedWhenFinalized();
    }
}

consumers

public class CookBurgerConsumer : IConsumer<CookBurger>
{
    public async Task Consume(ConsumeContext<CookBurger> context)
    {
        if (context.Message.CookTemp.Equals("90Degree"))
        {
            await Task.Delay(2000);
        }

        await context.Publish(new BurgerCookerFinishedCookingEvent()
        {
            CorrelationId = context.Message.CorrelationId
        });
    }
} 

Controller

public class BurgerController : ControllerBase
{
    private readonly IRequestClient<BurgerCookerOrderedEvent> _requestClient;
    public BurgerController(IRequestClient<BurgerCookerOrderedEvent> requestClient)
    {
        _requestClient = requestClient;
    }
    [HttpPost("burgerOrder")]
    public async Task<IActionResult> PlaceBurgerOrder()
    { 
        var order = new BurgerCookerOrderedEvent()
        {
            CorrelationId = Guid.NewGuid(),
            CustomerName = "JOHN-BOB",
            CookTemp = "MED"
        };
       var response = await _requestClient.GetResponse<SagaCompletionNotification>(order);
        if (response.Message != null)
        {
            return Ok("Burger Cooked Successfully");
        } 
        return StatusCode(500, "Burger cooking process failed");
    }
} 

EVENTS

namespace Order.Application.Saga.BurgerSaga
{
    public class BurgerCookerState : SagaStateMachineInstance
    {
        public Guid CorrelationId { get; set; }
        public int CurrentState { get; set; }
        public string CustomerName { get; set; }
        public string CookTemp { get; set; }

    }
    public record BurgerCookerOrderedEvent
    {
        public Guid CorrelationId { get; set; }
        public string CustomerName { get; set; }
        public string CookTemp { get; set; }

    }  
    public record BurgerCookerBeginCookingEvent
    {
        public Guid CorrelationId { get; set; }
        public string CustomerName { get; set; }
        public string CookTemp { get; set; } 
    }
    public record BurgerCookerFinishedCookingEvent
    {
        public Guid CorrelationId { get; set; } 
    }
    public class SagaCompletionNotification
    {
        public Guid CorrelationId { get; set; }
    }
    public class CookBurger
    {
        public string CookTemp { get; set; }
        public Guid CorrelationId { get; set; }

    }
}

Upvotes: 0

Views: 29

Answers (0)

Related Questions