使用自动机时状态机不一致

问题描述

我是微服务的新手,并自动使用了masstransit。目前,我的状态机在执行时显示不一致。第二个事件完成后,“内部”中的代码最初会按预期工作,但控制流不会在“内部”中执行代码。这仅对一个状态机发生,所有其他状态机均按预期工作。当我将“期间”中的代码移动到“最初”(最初已注释的代码)时,它可以正常工作。 下面是我的状态机的样子:

 InstanceState(x => x.CurrentState);
        Event(() => ServiceRequest1Registered,x => x.CorrelateById(context => context.Message.AggregateId));
        Event(() => ServiceRequest2Registered,x => x.CorrelateById(context => context.Message.AggregateId));

        Initially(
           When(ServiceRequest1Registered,context => context.Data.ServiceTypeId != (int)ServiceType.IndividualService)
           .Then(context => _logger.Loginformation($"When Initially,ServiceRequest1Registered and wrong condition"))
           .Finalize(),When(ServiceRequest1Registered,context => context.Data.ServiceTypeId == (int)ServiceType.IndividualService)
           .Then(context => _logger.Loginformation($"When Initially and ServiceRequest1Registered"))
           .Send(url,x => new ServiceRequest2RegisteredCommand
               {
                   InitiatedBy = x.Instance.InitiatedBy,ServiceRequestId = x.Instance.Id,Schedules = _mapper.Map<List<ScheduleDTO>>(x.Data.ServiceRequest1Schedules)
               })
           .Then(context => _logger.Loginformation($"Send ServiceRequest2RegisteredCommand")
           .TransitionTo(ServiceRequest1RegisterCompleted)
           ////When(ServiceRequest2Registered)
           ////.Then(context => _logger.Loginformation($"When ServiceRequestRegister2Completed and ServiceRequest2Registered"))
           //// .Finalize())
           );

        During(ServiceRequestRegister1Completed,Ignore(ServiceRequest1Registered),When(ServiceRequest2Registered)
           .Then(context => _logger.Loginformation($"When ServiceRequestRegister1Completed and ServiceRequest2Registered"))
            .Finalize());

        SetCompleted(async instance =>
        {
            State<ServiceRequestState> currentState = await this.GetState(instance);

            _logger.Loginformation($"Final state : {ServiceRequest2Registered.Equals(currentState)}");
            return ServiceRequest2Registered.Equals(currentState);
        });

通过下面的RabbitMQ进行大众运输设置

services.AddMasstransit(x =>
        {
            x.AddBus(provider => Masstransit.Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                cfg.Host(hostUri,hst =>
                {
                    hst.Username(appSettings.RabbitMQ.Username);
                    hst.Password(appSettings.RabbitMQ.Password);
                });

                cfg.ReceiveEndpoint("microservice-response",e =>
                {
                    e.UseInMemoryOutBox();
                    AddConsumers(e,provider);
                    e.ConfigureSaga<ServiceRequestRegisterState>(provider);
                });
            }));

            x.AddSagaStateMachine<ServiceRequestRegisterStateMachine,ServiceRequestRegisterState>()
               .InMemoryRepository();
        });

        services.AddSingleton<IHostedService,MasstransitBusService>();

我尝试了SetCompleted和SetCompletedWhenFinalized()。我们正在使用Masstransit v6.2.1和自动名称v4.2.1。需要帮助来确定我们为什么会遇到此问题或实施是否有问题吗?

解决方法

如果要在“初始事件”完成之前观察传递到状态机的事件,则应将UseInMemoryOutbox添加到接收端点(在状态机配置之前)。这将延迟出站消息,直到状态机实例持续存在为止。我怀疑您正在使用乐观锁定策略,并且第二个事件是在初始事件持久性完成之前到达的。

,

第二事件的相关性ID不同。这导致第二事件最初开始。更正了该问题,其余所有工作正常。确保状态机中的所有事件都具有相同的correlationid,并确保在编排过程中此correlationid不变。