问题描述
我是微服务的新手,并自动使用了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不变。