【问题标题】:Rebus Saga fires IAmInitiatedBy multiple timesRebus Saga 多次触发 IAmInitiatedBy
【发布时间】:2016-03-03 07:47:51
【问题描述】:

我正在使用最新版本的 Rebus (0.99.35) 和 SimpleInjector (3.1.2)。在我的第一个示例项目中,我使用 SQL Server 进行传输和 Sagas。

问题是实现IAmInitiatedBy<StartTheSagaMessage>的Saga方法Handle(StartTheSagaMessage message)被调用了5次,我不明白为什么。此外,此方法会向自己发布一条总线从未收到的消息。

下面是配置代码:

var container = new Container();

var assemblies = AppDomain.CurrentDomain.GetAssemblies()
    .Where(i => i.FullName.StartsWith("Messages"));

container.RegisterCollection(typeof(IHandleMessages<>), assemblies);

var bus = Configure.With(new SimpleInjectorContainerAdapter(container))
    .Logging(l => l.Trace())
    .Transport(t => t.UseSqlServer(connectionstring, "Messages", "consumer"))
    .Routing(r => r.TypeBased().MapAssemblyOf<Job>("consumer"))
    .Sagas(s => s.StoreInSqlServer(connectionstring, "Sagas", "SagaIndexTable"))
    .Options(o =>
    {
        o.SetNumberOfWorkers(1);
        o.SetMaxParallelism(1);
    })
    .Start();

container.Verify();

bus.Subscribe<Step1FinishedMessage>().Wait();
bus.Subscribe<Step2FinishedMessage>().Wait();

var procId = Guid.NewGuid();
bus.Send(new StartTheSagaMessage() { ProcessId = procId });

还有传奇密码:

public class MySaga : Saga<MySagaData>,
    IAmInitiatedBy<StartTheSagaMessage>,
    IHandleMessages<Step1FinishedMessage>,
    IHandleMessages<Step2FinishedMessage>
{
    public IBus Bus { get; set; }

    protected override void CorrelateMessages(ICorrelationConfig<MySagaData> config)
    {
        config.Correlate<StartTheSagaMessage>(m => m.ProcessId, s => s.SagaProcessId);
        config.Correlate<Step1FinishedMessage>(m => m.ProcessId, s => s.SagaProcessId);
        config.Correlate<Step2FinishedMessage>(m => m.ProcessId, s => s.SagaProcessId);
    }

    public async Task Handle(StartTheSagaMessage message)
    {
        if (IsNew == false)
            return;

        Trace.TraceInformation("Mysaga - got StartTheSagaMessage: {0}", message.ProcessId);
        //The saga is started - Do some stuff - call webservices (in external handler)
        //When this step is finished the external process replies with a "step1FinishedMessage"
        this.Data.SagaProcessId = message.ProcessId;
        //Fake Step1FinishMessage (should be replied from external handler)
        await Bus.Send(new Step1FinishedMessage() { ProcessId = this.Data.SagaProcessId });
    }

    public async Task Handle(Step1FinishedMessage message)
    {
        Trace.TraceInformation("Mysaga - got Step1FinishedMessage: {0}", message.ProcessId);
        //Sagabehaviour when the Step1 is finished by the external handler
        this.Data.Step1Finished = true;
        //After dalying 10 seconds - Send a step2finishedmessage
        await Bus.Defer(TimeSpan.FromSeconds(10), new Step2FinishedMessage() { ProcessId = this.Data.SagaProcessId });
    }

    public async Task Handle(Step2FinishedMessage message)
    {
        await Task.Run(() =>
        //return Task.FromResult<void>(() => 
        {
            Trace.TraceInformation("Mysaga - got Step2FinishedMessage: {0}", message.ProcessId);
            //Step2 is handled - finished the saga
            this.Data.Step2Finished = true;
            this.MarkAsComplete();
        });
    }
}

完整样本基于solution available here

我做错了什么?

感谢您的帮助。

【问题讨论】:

  • 此处提供的解决方案使用 Autofac?
  • 是的。源解决方案也使用旧的 nuget 包。
  • 是的,我可以看到,更新所有包会产生无法编译的代码。
  • 不幸的是,我找不到使用新包的 sagas 示例。
  • SimpleInjectorContainerAdapter 来自哪里?

标签: sql-server servicebus simple-injector rebus saga


【解决方案1】:

我改变了 Saga 并且它起作用了。

我说:

    private IBus _bus;

    public MySaga(IBus bus)
    {
        _bus = bus;
    }

代替:

    public IBus Bus { get; set; }

然后它就起作用了!我不明白为什么,因为调试 Bus 在方法中不为空。

【讨论】:

  • 5 次调用表明一定有错误。您应该查看日志以了解问题所在。如果您登录到跟踪输出,您可能应该配置某种跟踪侦听器,将日志通过管道传输到某处的文件 - 或者(这是我推荐的),使用可用的不错的 .NET 日志库之一,例如优秀的Serilog
  • 不幸的是,日志中没有消息。感谢您对 Serilog 的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多