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

State machine inconsistency while using Automatonymous

我是微服务的新手,使用自动命名的公共交通工具。目前我的状态机在执行时显示不一致。 Initially 中的代码按预期工作,但控制流在第二个事件完成后不执行 During 中的代码。这只发生在 1 个状态机上,所有其他状态机都按预期工作。当我将 During 中的代码移动到 Initially(最初的注释代码)时,它工作正常。 下面是我的状态机的样子:

 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 和 automatonymous v4.2.1。需要帮助来确定我们遇到此问题的原因或实施是否存在问题?

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

第二个事件的关联 ID 不同。这导致第 2 个事件最初发生。更正了该问题,其余一切正常。确保状态机中的所有事件都具有相同的 correlationid,并且此 correlationid 在编排期间不会更改。